@furystack/rest-service 10.1.3 → 11.0.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 +36 -76
- package/README.md +10 -2
- package/esm/authenticate.d.ts +19 -0
- package/esm/authenticate.d.ts.map +1 -1
- package/esm/authenticate.js +19 -0
- package/esm/authenticate.js.map +1 -1
- package/esm/authorize.d.ts +19 -0
- package/esm/authorize.d.ts.map +1 -1
- package/esm/authorize.js +19 -0
- package/esm/authorize.js.map +1 -1
- package/esm/endpoint-generators/create-get-entity-endpoint.spec.js +9 -9
- package/esm/endpoint-generators/create-get-entity-endpoint.spec.js.map +1 -1
- package/esm/endpoint-generators/create-get-swagger-json-action.d.ts +2 -2
- package/esm/endpoint-generators/create-get-swagger-json-action.d.ts.map +1 -1
- package/esm/endpoint-generators/create-patch-endpoint.spec.js +6 -6
- package/esm/endpoint-generators/create-patch-endpoint.spec.js.map +1 -1
- package/esm/endpoint-generators/create-post-endpoint.spec.js +6 -6
- package/esm/endpoint-generators/create-post-endpoint.spec.js.map +1 -1
- package/esm/get-schema-from-api.d.ts.map +1 -1
- package/esm/get-schema-from-api.js +6 -3
- package/esm/get-schema-from-api.js.map +1 -1
- package/esm/get-schema-from-api.spec.js +14 -12
- package/esm/get-schema-from-api.spec.js.map +1 -1
- package/esm/proxy-manager.spec.js +1 -1
- package/esm/proxy-manager.spec.js.map +1 -1
- package/esm/read-post-body.js.map +1 -1
- package/esm/rest-service.integration.spec.js +10 -10
- package/esm/rest-service.integration.spec.js.map +1 -1
- package/esm/server-response-extensions.js.map +1 -1
- package/esm/server-response-extensions.spec.d.ts.map +1 -1
- package/esm/server-response-extensions.spec.js +3 -3
- package/esm/server-response-extensions.spec.js.map +1 -1
- package/esm/swagger/generate-swagger-json.d.ts +2 -2
- package/esm/swagger/generate-swagger-json.d.ts.map +1 -1
- package/esm/swagger/generate-swagger-json.js +71 -69
- package/esm/swagger/generate-swagger-json.js.map +1 -1
- package/esm/swagger/generate-swagger-json.spec.js +97 -86
- package/esm/swagger/generate-swagger-json.spec.js.map +1 -1
- package/esm/validate.d.ts +27 -6
- package/esm/validate.d.ts.map +1 -1
- package/esm/validate.integration.schema.d.ts +10 -5
- package/esm/validate.integration.schema.d.ts.map +1 -1
- package/esm/validate.integration.spec.js +76 -31
- package/esm/validate.integration.spec.js.map +1 -1
- package/esm/validate.integration.spec.schema.json +24 -31
- package/esm/validate.js +24 -22
- package/esm/validate.js.map +1 -1
- package/package.json +10 -10
- package/src/authenticate.ts +19 -0
- package/src/authorize.ts +19 -0
- package/src/endpoint-generators/create-get-entity-endpoint.spec.ts +9 -9
- package/src/endpoint-generators/create-get-swagger-json-action.ts +2 -2
- package/src/endpoint-generators/create-patch-endpoint.spec.ts +6 -6
- package/src/endpoint-generators/create-post-endpoint.spec.ts +6 -6
- package/src/get-schema-from-api.spec.ts +14 -12
- package/src/get-schema-from-api.ts +13 -8
- package/src/proxy-manager.spec.ts +4 -4
- package/src/read-post-body.ts +1 -1
- package/src/rest-service.integration.spec.ts +10 -10
- package/src/server-response-extensions.spec.ts +8 -8
- package/src/server-response-extensions.ts +1 -1
- package/src/swagger/generate-swagger-json.spec.ts +107 -96
- package/src/swagger/generate-swagger-json.ts +80 -71
- package/src/validate.integration.schema.ts +11 -5
- package/src/validate.integration.spec.schema.json +24 -31
- package/src/validate.integration.spec.ts +84 -36
- package/src/validate.ts +61 -32
package/CHANGELOG.md
CHANGED
|
@@ -1,88 +1,48 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
3
|
+
## [11.0.0] - 2026-01-22
|
|
5
4
|
|
|
6
|
-
###
|
|
5
|
+
### 💥 Breaking Changes
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
### ApiEndpointSchema structure changed
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
The `ApiEndpointSchema` generic type now requires endpoints to be grouped by HTTP method.
|
|
11
10
|
|
|
12
|
-
**
|
|
11
|
+
**Before:**
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"name": "My Endpoint",
|
|
16
|
+
"description": "My Endpoint Description",
|
|
17
|
+
"version": "5.2.1",
|
|
18
|
+
"endpoints": {
|
|
19
|
+
"/entity": {...}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
15
23
|
|
|
16
|
-
**
|
|
24
|
+
**After:**
|
|
17
25
|
|
|
18
|
-
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"name": "My Endpoint",
|
|
29
|
+
"description": "My Endpoint Description",
|
|
30
|
+
"version": "5.2.1",
|
|
31
|
+
"endpoints": {
|
|
32
|
+
"GET": {
|
|
33
|
+
"/entity": {...}
|
|
34
|
+
},
|
|
35
|
+
"POST": {
|
|
36
|
+
"/entity": {...}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
19
41
|
|
|
20
|
-
|
|
42
|
+
### ⬆️ Dependencies
|
|
21
43
|
|
|
22
|
-
|
|
44
|
+
- Dependency updates
|
|
23
45
|
|
|
24
|
-
|
|
46
|
+
### 🔧 Chores
|
|
25
47
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
**Note:** Version bump only for package @furystack/rest-service
|
|
29
|
-
|
|
30
|
-
### [4.1.4](https://github.com/furystack/furystack/compare/@furystack/rest-service@4.1.3...@furystack/rest-service@4.1.4) (2021-11-30)
|
|
31
|
-
|
|
32
|
-
**Note:** Version bump only for package @furystack/rest-service
|
|
33
|
-
|
|
34
|
-
### [4.1.3](https://github.com/furystack/furystack/compare/@furystack/rest-service@4.1.2...@furystack/rest-service@4.1.3) (2021-11-29)
|
|
35
|
-
|
|
36
|
-
**Note:** Version bump only for package @furystack/rest-service
|
|
37
|
-
|
|
38
|
-
### [4.1.2](https://github.com/furystack/furystack/compare/@furystack/rest-service@4.1.1...@furystack/rest-service@4.1.2) (2021-11-19)
|
|
39
|
-
|
|
40
|
-
**Note:** Version bump only for package @furystack/rest-service
|
|
41
|
-
|
|
42
|
-
### [4.1.1](https://github.com/furystack/furystack/compare/@furystack/rest-service@4.1.0...@furystack/rest-service@4.1.1) (2021-11-17)
|
|
43
|
-
|
|
44
|
-
**Note:** Version bump only for package @furystack/rest-service
|
|
45
|
-
|
|
46
|
-
## [4.1.0](https://github.com/furystack/furystack/compare/@furystack/rest-service@4.0.21...@furystack/rest-service@4.1.0) (2021-11-09)
|
|
47
|
-
|
|
48
|
-
### 🚀 What's new
|
|
49
|
-
|
|
50
|
-
- **@furystack/rest-service:** disabled strict mode for schema validation ([20a9bad](https://github.com/furystack/furystack/commit/20a9bad9368b06b6b3186273b767dbb690e6473a))
|
|
51
|
-
|
|
52
|
-
### [4.0.21](https://github.com/furystack/furystack/compare/@furystack/rest-service@4.0.20...@furystack/rest-service@4.0.21) (2021-10-15)
|
|
53
|
-
|
|
54
|
-
**Note:** Version bump only for package @furystack/rest-service
|
|
55
|
-
|
|
56
|
-
### [4.0.20](https://github.com/furystack/furystack/compare/@furystack/rest-service@4.0.19...@furystack/rest-service@4.0.20) (2021-10-05)
|
|
57
|
-
|
|
58
|
-
**Note:** Version bump only for package @furystack/rest-service
|
|
59
|
-
|
|
60
|
-
### [4.0.19](https://github.com/furystack/furystack/compare/@furystack/rest-service@4.0.18...@furystack/rest-service@4.0.19) (2021-09-16)
|
|
61
|
-
|
|
62
|
-
**Note:** Version bump only for package @furystack/rest-service
|
|
63
|
-
|
|
64
|
-
### [4.0.18](https://github.com/furystack/furystack/compare/@furystack/rest-service@4.0.17...@furystack/rest-service@4.0.18) (2021-08-27)
|
|
65
|
-
|
|
66
|
-
**Note:** Version bump only for package @furystack/rest-service
|
|
67
|
-
|
|
68
|
-
### [4.0.17](https://github.com/furystack/furystack/compare/@furystack/rest-service@4.0.16...@furystack/rest-service@4.0.17) (2021-08-25)
|
|
69
|
-
|
|
70
|
-
**Note:** Version bump only for package @furystack/rest-service
|
|
71
|
-
|
|
72
|
-
### [4.0.16](https://github.com/furystack/furystack/compare/@furystack/rest-service@4.0.15...@furystack/rest-service@4.0.16) (2021-08-19)
|
|
73
|
-
|
|
74
|
-
**Note:** Version bump only for package @furystack/rest-service
|
|
75
|
-
|
|
76
|
-
### [4.0.15](https://github.com/furystack/furystack/compare/@furystack/rest-service@2.3.2...@furystack/rest-service@4.0.15) (2021-08-19)
|
|
77
|
-
|
|
78
|
-
### 🐛 Bug Fixes
|
|
79
|
-
|
|
80
|
-
- **rest-service:** cookie logout ([d1b04c6](https://github.com/furystack/furystack/commit/d1b04c6d976951b74c7880ab57e5676618dd5bb2))
|
|
81
|
-
- **rest-service:** remove session by its id ([14d9729](https://github.com/furystack/furystack/commit/14d9729c1e9581bb86ef0d87b93b3ec65056bc29))
|
|
82
|
-
|
|
83
|
-
### [4.0.14](https://github.com/furystack/furystack/compare/@furystack/rest-service@2.3.2...@furystack/rest-service@4.0.14) (2021-07-30)
|
|
84
|
-
|
|
85
|
-
### 🐛 Bug Fixes
|
|
86
|
-
|
|
87
|
-
- **rest-service:** cookie logout ([d1b04c6](https://github.com/furystack/furystack/commit/d1b04c6d976951b74c7880ab57e5676618dd5bb2))
|
|
88
|
-
- **rest-service:** remove session by its id ([14d9729](https://github.com/furystack/furystack/commit/14d9729c1e9581bb86ef0d87b93b3ec65056bc29))
|
|
48
|
+
- Migrated to centralized changelog management system
|
package/README.md
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
# rest-service
|
|
1
|
+
# @furystack/rest-service
|
|
2
2
|
|
|
3
3
|
REST service (implementation) package for `@furystack/rest`.
|
|
4
4
|
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @furystack/rest-service
|
|
9
|
+
# or
|
|
10
|
+
yarn add @furystack/rest-service
|
|
11
|
+
```
|
|
12
|
+
|
|
5
13
|
## Usage
|
|
6
14
|
|
|
7
15
|
Start by importing your custom API endpoint interface (see `@furystack/rest`) and use the `.useRestService<MyApi>(...)` injector extension method. You can define multiple REST services per injector (even on the same port).
|
|
@@ -117,7 +125,7 @@ await useRestService<MyApiWithCustomEndpoint>({
|
|
|
117
125
|
getUrlParams,
|
|
118
126
|
headers,
|
|
119
127
|
injector,
|
|
120
|
-
// request, // This will be the plain IncomingMessage - you can use it for lower level
|
|
128
|
+
// request, // This will be the plain IncomingMessage - you can use it for lower level functionality, e.g. parsing form data
|
|
121
129
|
// response, // This will be the plain ServerResponse - you can use it for lower level functionality, e.g. streaming binaries
|
|
122
130
|
}) => {
|
|
123
131
|
const body = await getBody() // Body type will be resolved
|
package/esm/authenticate.d.ts
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
import type { RequestAction } from './request-action-implementation.js';
|
|
2
|
+
/**
|
|
3
|
+
* Higher-order function that wraps a request action to require authentication.
|
|
4
|
+
* If the user is not authenticated, returns a 401 Unauthorized response.
|
|
5
|
+
* Includes a random delay on unauthorized requests to mitigate timing attacks.
|
|
6
|
+
*
|
|
7
|
+
* @returns A function that wraps the provided action with authentication check
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* // Wrap an endpoint to require authentication
|
|
11
|
+
* const protectedEndpoint = Authenticate()(myEndpoint)
|
|
12
|
+
*
|
|
13
|
+
* // Or use directly in API definition
|
|
14
|
+
* api: {
|
|
15
|
+
* GET: {
|
|
16
|
+
* '/users': Authenticate()(getUsersEndpoint)
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
2
21
|
export declare const Authenticate: () => <T extends {
|
|
3
22
|
result: unknown;
|
|
4
23
|
}>(action: RequestAction<T>) => RequestAction<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticate.d.ts","sourceRoot":"","sources":["../src/authenticate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,aAAa,EAAwB,MAAM,oCAAoC,CAAA;AAG3G,eAAO,MAAM,YAAY,SAEtB,CAAC,SAAS;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,EAAE,QAAQ,aAAa,CAAC,CAAC,CAAC,KAAG,aAAa,CAAC,CAAC,CAkBzE,CAAA"}
|
|
1
|
+
{"version":3,"file":"authenticate.d.ts","sourceRoot":"","sources":["../src/authenticate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,aAAa,EAAwB,MAAM,oCAAoC,CAAA;AAG3G;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,YAAY,SAEtB,CAAC,SAAS;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,EAAE,QAAQ,aAAa,CAAC,CAAC,CAAC,KAAG,aAAa,CAAC,CAAC,CAkBzE,CAAA"}
|
package/esm/authenticate.js
CHANGED
|
@@ -2,6 +2,25 @@ import { isAuthenticated } from '@furystack/core';
|
|
|
2
2
|
import { sleepAsync } from '@furystack/utils';
|
|
3
3
|
import { HttpUserContext } from './http-user-context.js';
|
|
4
4
|
import { JsonResult } from './request-action-implementation.js';
|
|
5
|
+
/**
|
|
6
|
+
* Higher-order function that wraps a request action to require authentication.
|
|
7
|
+
* If the user is not authenticated, returns a 401 Unauthorized response.
|
|
8
|
+
* Includes a random delay on unauthorized requests to mitigate timing attacks.
|
|
9
|
+
*
|
|
10
|
+
* @returns A function that wraps the provided action with authentication check
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // Wrap an endpoint to require authentication
|
|
14
|
+
* const protectedEndpoint = Authenticate()(myEndpoint)
|
|
15
|
+
*
|
|
16
|
+
* // Or use directly in API definition
|
|
17
|
+
* api: {
|
|
18
|
+
* GET: {
|
|
19
|
+
* '/users': Authenticate()(getUsersEndpoint)
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
5
24
|
export const Authenticate = () => (action) => {
|
|
6
25
|
const wrapped = async (args) => {
|
|
7
26
|
const { injector } = args;
|
package/esm/authenticate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticate.js","sourceRoot":"","sources":["../src/authenticate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AAE/D,MAAM,CAAC,MAAM,YAAY,GACvB,GAAG,EAAE,CACL,CAAgC,MAAwB,EAAoB,EAAE;IAC5E,MAAM,OAAO,GAAG,KAAK,EAAE,IAA6B,EAA4B,EAAE;QAChF,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAA;QACzB,MAAM,aAAa,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAA;QACrD,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;YACtC,OAAO,UAAU,CACf,EAAE,KAAK,EAAE,cAAc,EAAE,EACzB,GAAG,EACH,QAAQ,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAC9E,CAAA;QACjC,CAAC;QACD,OAAO,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAoB,CAAA;IAChD,CAAC,CAAA;IAED,OAAO,CAAC,eAAe,GAAG,IAAI,CAAA;IAE9B,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"authenticate.js","sourceRoot":"","sources":["../src/authenticate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAA;AAE/D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,YAAY,GACvB,GAAG,EAAE,CACL,CAAgC,MAAwB,EAAoB,EAAE;IAC5E,MAAM,OAAO,GAAG,KAAK,EAAE,IAA6B,EAA4B,EAAE;QAChF,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAA;QACzB,MAAM,aAAa,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAA;QACrD,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;YACtC,OAAO,UAAU,CACf,EAAE,KAAK,EAAE,cAAc,EAAE,EACzB,GAAG,EACH,QAAQ,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAC9E,CAAA;QACjC,CAAC;QACD,OAAO,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAoB,CAAA;IAChD,CAAC,CAAA;IAED,OAAO,CAAC,eAAe,GAAG,IAAI,CAAA;IAE9B,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
|
package/esm/authorize.d.ts
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
import type { RequestAction } from './request-action-implementation.js';
|
|
2
|
+
/**
|
|
3
|
+
* Higher-order function that wraps a request action to require specific roles.
|
|
4
|
+
* If the user does not have the required roles, throws an AuthorizationError.
|
|
5
|
+
* Includes a random delay on unauthorized requests to mitigate timing attacks.
|
|
6
|
+
*
|
|
7
|
+
* @param roles - The roles required to access the endpoint
|
|
8
|
+
* @returns A function that wraps the provided action with authorization check
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // Require 'admin' role
|
|
12
|
+
* const adminEndpoint = Authorize('admin')(myEndpoint)
|
|
13
|
+
*
|
|
14
|
+
* // Require multiple roles (user must have ALL specified roles)
|
|
15
|
+
* const superAdminEndpoint = Authorize('admin', 'superuser')(myEndpoint)
|
|
16
|
+
*
|
|
17
|
+
* // Chain with Authenticate for authentication + authorization
|
|
18
|
+
* const protectedEndpoint = Authenticate()(Authorize('admin')(myEndpoint))
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
2
21
|
export declare const Authorize: (...roles: string[]) => <T extends {
|
|
3
22
|
result: unknown;
|
|
4
23
|
}>(action: RequestAction<T>) => RequestAction<T>;
|
package/esm/authorize.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../src/authorize.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAgB,aAAa,EAAwB,MAAM,oCAAoC,CAAA;AAE3G,eAAO,MAAM,SAAS,GACnB,GAAG,OAAO,MAAM,EAAE,MAClB,CAAC,SAAS;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,EAAE,QAAQ,aAAa,CAAC,CAAC,CAAC,KAAG,aAAa,CAAC,CAAC,CAazE,CAAA"}
|
|
1
|
+
{"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../src/authorize.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAgB,aAAa,EAAwB,MAAM,oCAAoC,CAAA;AAE3G;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,SAAS,GACnB,GAAG,OAAO,MAAM,EAAE,MAClB,CAAC,SAAS;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,EAAE,QAAQ,aAAa,CAAC,CAAC,CAAC,KAAG,aAAa,CAAC,CAAC,CAazE,CAAA"}
|
package/esm/authorize.js
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import { AuthorizationError, isAuthorized } from '@furystack/core';
|
|
2
2
|
import { sleepAsync } from '@furystack/utils';
|
|
3
|
+
/**
|
|
4
|
+
* Higher-order function that wraps a request action to require specific roles.
|
|
5
|
+
* If the user does not have the required roles, throws an AuthorizationError.
|
|
6
|
+
* Includes a random delay on unauthorized requests to mitigate timing attacks.
|
|
7
|
+
*
|
|
8
|
+
* @param roles - The roles required to access the endpoint
|
|
9
|
+
* @returns A function that wraps the provided action with authorization check
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* // Require 'admin' role
|
|
13
|
+
* const adminEndpoint = Authorize('admin')(myEndpoint)
|
|
14
|
+
*
|
|
15
|
+
* // Require multiple roles (user must have ALL specified roles)
|
|
16
|
+
* const superAdminEndpoint = Authorize('admin', 'superuser')(myEndpoint)
|
|
17
|
+
*
|
|
18
|
+
* // Chain with Authenticate for authentication + authorization
|
|
19
|
+
* const protectedEndpoint = Authenticate()(Authorize('admin')(myEndpoint))
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
3
22
|
export const Authorize = (...roles) => (action) => {
|
|
4
23
|
return async (options) => {
|
|
5
24
|
try {
|
package/esm/authorize.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorize.js","sourceRoot":"","sources":["../src/authorize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAG7C,MAAM,CAAC,MAAM,SAAS,GACpB,CAAC,GAAG,KAAe,EAAE,EAAE,CACvB,CAAgC,MAAwB,EAAoB,EAAE;IAC5E,OAAO,KAAK,EAAE,OAAgC,EAA4B,EAAE;QAC1E,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,CAAA;YACjE,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;gBACtC,MAAM,IAAI,kBAAkB,CAAC,WAAW,CAAC,CAAA;YAC3C,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,kBAAkB,CAAC,WAAW,CAAC,CAAA;QAC3C,CAAC;QACD,OAAO,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAoB,CAAA;IACnD,CAAC,CAAA;AACH,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"authorize.js","sourceRoot":"","sources":["../src/authorize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAG7C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,SAAS,GACpB,CAAC,GAAG,KAAe,EAAE,EAAE,CACvB,CAAgC,MAAwB,EAAoB,EAAE;IAC5E,OAAO,KAAK,EAAE,OAAgC,EAA4B,EAAE;QAC1E,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,CAAA;YACjE,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;gBACtC,MAAM,IAAI,kBAAkB,CAAC,WAAW,CAAC,CAAA;YAC3C,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,kBAAkB,CAAC,WAAW,CAAC,CAAA;QAC3C,CAAC;QACD,OAAO,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAoB,CAAA;IACnD,CAAC,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getPort } from '@furystack/core/port-generator';
|
|
2
2
|
import { Injector } from '@furystack/inject';
|
|
3
|
-
import { serializeToQueryString } from '@furystack/rest';
|
|
4
|
-
import { MockClass, setupContext } from './utils.js';
|
|
5
|
-
import { createGetEntityEndpoint } from './create-get-entity-endpoint.js';
|
|
6
3
|
import { getDataSetFor } from '@furystack/repository';
|
|
4
|
+
import { serializeToQueryString } from '@furystack/rest';
|
|
5
|
+
import { usingAsync } from '@furystack/utils';
|
|
6
|
+
import { describe, expect, it } from 'vitest';
|
|
7
7
|
import { useRestService } from '../helpers.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { createGetEntityEndpoint } from './create-get-entity-endpoint.js';
|
|
9
|
+
import { MockClass, setupContext } from './utils.js';
|
|
10
10
|
describe('createGetEntityEndpoint', () => {
|
|
11
11
|
it('Should return the entity', async () => {
|
|
12
12
|
await usingAsync(new Injector(), async (i) => {
|
|
@@ -26,7 +26,7 @@ describe('createGetEntityEndpoint', () => {
|
|
|
26
26
|
await getDataSetFor(i, MockClass, 'id').add(i, mockEntity);
|
|
27
27
|
const response = await fetch(`http://127.0.0.1:${port}/api/mock`, { method: 'GET' });
|
|
28
28
|
expect(response.status).toBe(200);
|
|
29
|
-
const body = await response.json();
|
|
29
|
+
const body = (await response.json());
|
|
30
30
|
expect(body).toEqual(mockEntity);
|
|
31
31
|
});
|
|
32
32
|
});
|
|
@@ -50,7 +50,7 @@ describe('createGetEntityEndpoint', () => {
|
|
|
50
50
|
method: 'GET',
|
|
51
51
|
});
|
|
52
52
|
expect(response.status).toBe(200);
|
|
53
|
-
const body = await response.json();
|
|
53
|
+
const body = (await response.json());
|
|
54
54
|
expect(body).toEqual({ id: mockEntity.id });
|
|
55
55
|
});
|
|
56
56
|
});
|
|
@@ -70,7 +70,7 @@ describe('createGetEntityEndpoint', () => {
|
|
|
70
70
|
});
|
|
71
71
|
const result = await fetch(`http://127.0.0.1:${port}/api/mock`, { method: 'GET' });
|
|
72
72
|
expect(result.status).toBe(404);
|
|
73
|
-
const body = await result.json();
|
|
73
|
+
const body = (await result.json());
|
|
74
74
|
expect(body).toEqual({ message: 'Entity not found' });
|
|
75
75
|
});
|
|
76
76
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-get-entity-endpoint.spec.js","sourceRoot":"","sources":["../../src/endpoint-generators/create-get-entity-endpoint.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"create-get-entity-endpoint.spec.js","sourceRoot":"","sources":["../../src/endpoint-generators/create-get-entity-endpoint.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ApiEndpointSchema, type SwaggerDocument } from '@furystack/rest';
|
|
2
2
|
import type { RestApiImplementation } from '../api-manager.js';
|
|
3
3
|
import { type RequestAction } from '../request-action-implementation.js';
|
|
4
|
-
export type GetSchemaResult =
|
|
4
|
+
export type GetSchemaResult = ApiEndpointSchema['endpoints'];
|
|
5
5
|
/**
|
|
6
6
|
* Generates a RequestAction that retrieves the Swagger JSON schema from a FuryStack API implementation.
|
|
7
7
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-get-swagger-json-action.d.ts","sourceRoot":"","sources":["../../src/endpoint-generators/create-get-swagger-json-action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"create-get-swagger-json-action.d.ts","sourceRoot":"","sources":["../../src/endpoint-generators/create-get-swagger-json-action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC9E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAE9D,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,qCAAqC,CAAA;AAGpF,MAAM,MAAM,eAAe,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAA;AAE5D;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,GAAI,CAAC,SAAS,qBAAqB,CAAC,GAAG,CAAC,EAC7E,KAAK,CAAC,EACN,aAAsB,EACtB,oBAAqE,EACrE,gBAAiB,KAChB,aAAa,CAAC;IAAE,MAAM,EAAE,eAAe,GAAG,eAAe,CAAA;CAAE,CAM7D,CAAA"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getPort } from '@furystack/core/port-generator';
|
|
2
2
|
import { Injector } from '@furystack/inject';
|
|
3
|
-
import { createPatchEndpoint } from './create-patch-endpoint.js';
|
|
4
|
-
import { MockClass, setupContext } from './utils.js';
|
|
5
3
|
import { getDataSetFor } from '@furystack/repository';
|
|
4
|
+
import { usingAsync } from '@furystack/utils';
|
|
5
|
+
import { describe, expect, it } from 'vitest';
|
|
6
6
|
import { useRestService } from '../helpers.js';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { createPatchEndpoint } from './create-patch-endpoint.js';
|
|
8
|
+
import { MockClass, setupContext } from './utils.js';
|
|
9
9
|
describe('createPatchEndpoint', () => {
|
|
10
10
|
it('Should update the entity and report the success', async () => {
|
|
11
11
|
await usingAsync(new Injector(), async (i) => {
|
|
@@ -29,7 +29,7 @@ describe('createPatchEndpoint', () => {
|
|
|
29
29
|
body: JSON.stringify({ value: 'updated' }),
|
|
30
30
|
});
|
|
31
31
|
expect(response.status).toBe(200);
|
|
32
|
-
const body = await response.json();
|
|
32
|
+
const body = (await response.json());
|
|
33
33
|
expect(body).toEqual({});
|
|
34
34
|
const updated = await getDataSetFor(i, MockClass, 'id').get(i, 'mock');
|
|
35
35
|
expect(updated?.value).toBe('updated');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-patch-endpoint.spec.js","sourceRoot":"","sources":["../../src/endpoint-generators/create-patch-endpoint.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"create-patch-endpoint.spec.js","sourceRoot":"","sources":["../../src/endpoint-generators/create-patch-endpoint.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAErD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEpD,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,UAAU,CAAC,IAAI,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;YAC3C,YAAY,CAAC,CAAC,CAAC,CAAA;YACf,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;YACtB,MAAM,cAAc,CAAwD;gBAC1E,QAAQ,EAAE,CAAC;gBACX,IAAI,EAAE,MAAM;gBACZ,IAAI;gBACJ,GAAG,EAAE;oBACH,KAAK,EAAE;wBACL,MAAM,EAAE,mBAAmB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;qBACpE;iBACF;aACF,CAAC,CAAA;YACF,MAAM,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;YAE7E,MAAM,iBAAiB,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YAC1E,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAEjC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,WAAW,EAAE;gBAChE,MAAM,EAAE,OAAO;gBACf,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;aAC3C,CAAC,CAAA;YACF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACjC,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAsB,CAAA;YACzD,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;YACxB,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;YACtE,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACxC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getPort } from '@furystack/core/port-generator';
|
|
2
2
|
import { Injector } from '@furystack/inject';
|
|
3
|
+
import { getDataSetFor } from '@furystack/repository';
|
|
4
|
+
import { usingAsync } from '@furystack/utils';
|
|
5
|
+
import { describe, expect, it } from 'vitest';
|
|
6
|
+
import { useRestService } from '../helpers.js';
|
|
3
7
|
import { createPostEndpoint } from './create-post-endpoint.js';
|
|
4
8
|
import { MockClass, setupContext } from './utils.js';
|
|
5
|
-
import { useRestService } from '../helpers.js';
|
|
6
|
-
import { getDataSetFor } from '@furystack/repository';
|
|
7
|
-
import { describe, it, expect } from 'vitest';
|
|
8
|
-
import { getPort } from '@furystack/core/port-generator';
|
|
9
9
|
describe('createPostEndpoint', () => {
|
|
10
10
|
it('Should create the entity and report the success', async () => {
|
|
11
11
|
await usingAsync(new Injector(), async (i) => {
|
|
@@ -27,7 +27,7 @@ describe('createPostEndpoint', () => {
|
|
|
27
27
|
body: JSON.stringify(entityToPost),
|
|
28
28
|
});
|
|
29
29
|
expect(response.status).toBe(201);
|
|
30
|
-
const body = await response.json();
|
|
30
|
+
const body = (await response.json());
|
|
31
31
|
expect(body).toEqual(entityToPost);
|
|
32
32
|
const posted = await getDataSetFor(i, MockClass, 'id').get(i, entityToPost.id);
|
|
33
33
|
expect(posted?.value).toBe('posted');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-post-endpoint.spec.js","sourceRoot":"","sources":["../../src/endpoint-generators/create-post-endpoint.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"create-post-endpoint.spec.js","sourceRoot":"","sources":["../../src/endpoint-generators/create-post-endpoint.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAErD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEpD,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,UAAU,CAAC,IAAI,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;YAC3C,YAAY,CAAC,CAAC,CAAC,CAAA;YACf,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;YACtB,MAAM,cAAc,CAAmD;gBACrE,QAAQ,EAAE,CAAC;gBACX,IAAI,EAAE,MAAM;gBACZ,IAAI;gBACJ,GAAG,EAAE;oBACH,IAAI,EAAE;wBACJ,GAAG,EAAE,kBAAkB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;qBAChE;iBACF;aACF,CAAC,CAAA;YACF,MAAM,YAAY,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;YACpD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,MAAM,EAAE;gBAC3D,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC;aACnC,CAAC,CAAA;YACF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACjC,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAkC,CAAA;YACrE,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;YAClC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,CAAA;YAC9E,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACtC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-schema-from-api.d.ts","sourceRoot":"","sources":["../src/get-schema-from-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,iBAAiB,EAAU,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAG7D,eAAO,MAAM,aAAa,EAAE,MA2B3B,CAAA;
|
|
1
|
+
{"version":3,"file":"get-schema-from-api.d.ts","sourceRoot":"","sources":["../src/get-schema-from-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,iBAAiB,EAAU,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAG7D,eAAO,MAAM,aAAa,EAAE,MA2B3B,CAAA;AAcD,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,qBAAqB,CAAC,OAAO,CAAC,EAAE,sCAKxE;IACD,GAAG,EAAE,CAAC,CAAA;IACN,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,KAAG,iBAuBH,CAAA"}
|
|
@@ -27,9 +27,8 @@ export const defaultSchema = {
|
|
|
27
27
|
},
|
|
28
28
|
};
|
|
29
29
|
const defaultSchemaName = 'default';
|
|
30
|
-
const getDefinitionFromAction = (
|
|
30
|
+
const getDefinitionFromAction = (path, action) => {
|
|
31
31
|
return {
|
|
32
|
-
method,
|
|
33
32
|
path,
|
|
34
33
|
schema: 'schema' in action && typeof action.schema === 'object' ? action.schema : defaultSchema,
|
|
35
34
|
schemaName: 'schemaName' in action && typeof action.schemaName === 'string' ? action.schemaName : defaultSchemaName,
|
|
@@ -39,9 +38,13 @@ const getDefinitionFromAction = (method, path, action) => {
|
|
|
39
38
|
export const getSchemaFromApi = ({ api, name = 'FuryStack API', description = 'API documentation generated from FuryStack API schema', version = '1.0.0', }) => {
|
|
40
39
|
const endpoints = {};
|
|
41
40
|
Object.entries(api).forEach(([method, endpointList]) => {
|
|
41
|
+
const methodKey = method;
|
|
42
|
+
if (!endpoints[methodKey]) {
|
|
43
|
+
endpoints[methodKey] = {};
|
|
44
|
+
}
|
|
42
45
|
Object.entries(endpointList).forEach(([url, requestAction]) => {
|
|
43
46
|
if (method && url && requestAction) {
|
|
44
|
-
endpoints[url] = getDefinitionFromAction(
|
|
47
|
+
endpoints[methodKey][url] = getDefinitionFromAction(url, requestAction);
|
|
45
48
|
}
|
|
46
49
|
});
|
|
47
50
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-schema-from-api.js","sourceRoot":"","sources":["../src/get-schema-from-api.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,aAAa,GAAW;IACnC,WAAW,EAAE;QACX,OAAO,EAAE;YACP,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,IAAI;iBAC3B;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,IAAI;iBAC3B;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,IAAI;iBAC3B;gBACD,GAAG,EAAE;oBACH,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,IAAI;iBAC3B;aACF;YACD,QAAQ,EAAE,EAAE;YACZ,WAAW,EAAE,kCAAkC;YAC/C,oBAAoB,EAAE,IAAI;SAC3B;KACF;CACF,CAAA;AAED,MAAM,iBAAiB,GAAG,SAAS,CAAA;AAEnC,MAAM,uBAAuB,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"get-schema-from-api.js","sourceRoot":"","sources":["../src/get-schema-from-api.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,aAAa,GAAW;IACnC,WAAW,EAAE;QACX,OAAO,EAAE;YACP,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,IAAI;iBAC3B;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,IAAI;iBAC3B;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,IAAI;iBAC3B;gBACD,GAAG,EAAE;oBACH,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,IAAI;iBAC3B;aACF;YACD,QAAQ,EAAE,EAAE;YACZ,WAAW,EAAE,kCAAkC;YAC/C,oBAAoB,EAAE,IAAI;SAC3B;KACF;CACF,CAAA;AAED,MAAM,iBAAiB,GAAG,SAAS,CAAA;AAEnC,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAE,MAA0C,EAAyB,EAAE;IAClH,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,QAAQ,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa;QAC/F,UAAU,EAAE,YAAY,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,iBAAiB;QACnH,eAAe,EACb,iBAAiB,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK;KAC9G,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAA2C,EACzE,GAAG,EACH,IAAI,GAAG,eAAe,EACtB,WAAW,GAAG,uDAAuD,EACrE,OAAO,GAAG,OAAO,GAMlB,EAAqB,EAAE;IACtB,MAAM,SAAS,GAAmC,EAAE,CAAA;IAEpD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,EAAE;QACrD,MAAM,SAAS,GAAG,MAAgB,CAAA;QAClC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,CAAA;QAC3B,CAAC;QACD,MAAM,CAAC,OAAO,CAAC,YAAkE,CAAC,CAAC,OAAO,CACxF,CAAC,CAAC,GAAG,EAAE,aAAa,CAAC,EAAE,EAAE;YACvB,IAAI,MAAM,IAAI,GAAG,IAAI,aAAa,EAAE,CAAC;gBACnC,SAAS,CAAC,SAAS,CAAE,CAAC,GAAG,CAAC,GAAG,uBAAuB,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;YAC1E,CAAC;QACH,CAAC,CACF,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,IAAI;QACJ,WAAW;QACX,OAAO;QACP,SAAS;KACV,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -24,12 +24,13 @@ describe('getSchemaFromApi', () => {
|
|
|
24
24
|
description: 'Test API Description',
|
|
25
25
|
version: '1.0.0',
|
|
26
26
|
endpoints: {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
GET: {
|
|
28
|
+
'/example': {
|
|
29
|
+
isAuthenticated: false,
|
|
30
|
+
path: '/example',
|
|
31
|
+
schema: defaultSchema,
|
|
32
|
+
schemaName: 'default',
|
|
33
|
+
},
|
|
33
34
|
},
|
|
34
35
|
},
|
|
35
36
|
});
|
|
@@ -54,12 +55,13 @@ describe('getSchemaFromApi', () => {
|
|
|
54
55
|
description: 'Test API Description',
|
|
55
56
|
version: '1.0.0',
|
|
56
57
|
endpoints: {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
GET: {
|
|
59
|
+
'/validate-query': {
|
|
60
|
+
isAuthenticated: false,
|
|
61
|
+
path: '/validate-query',
|
|
62
|
+
schema: validationSchema,
|
|
63
|
+
schemaName: 'ValidateQuery',
|
|
64
|
+
},
|
|
63
65
|
},
|
|
64
66
|
},
|
|
65
67
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-schema-from-api.spec.js","sourceRoot":"","sources":["../src/get-schema-from-api.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC1E,OAAO,EAAE,UAAU,EAAsB,MAAM,oCAAoC,CAAA;AACnF,OAAO,gBAAgB,MAAM,yCAAyC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AAC5F,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC,MAAM,aAAa,GAAuB,KAAK,IAAI,EAAE;IACnD,OAAO,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;AACtC,CAAC,CAAA;AAED,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,GAAG,GAAG;YACV,GAAG,EAAE;gBACH,UAAU,EAAE,aAAa;aAC1B;SAC4C,CAAA;QAE/C,MAAM,MAAM,GAAG,gBAAgB,CAAC;YAC9B,GAAG,EAAE,GAAG;YACR,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE,sBAAsB;YACnC,OAAO,EAAE,OAAO;SACjB,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE,sBAAsB;YACnC,OAAO,EAAE,OAAO;YAChB,SAAS,EAAE;gBACT,UAAU,EAAE;
|
|
1
|
+
{"version":3,"file":"get-schema-from-api.spec.js","sourceRoot":"","sources":["../src/get-schema-from-api.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC1E,OAAO,EAAE,UAAU,EAAsB,MAAM,oCAAoC,CAAA;AACnF,OAAO,gBAAgB,MAAM,yCAAyC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AAC5F,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC,MAAM,aAAa,GAAuB,KAAK,IAAI,EAAE;IACnD,OAAO,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;AACtC,CAAC,CAAA;AAED,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,GAAG,GAAG;YACV,GAAG,EAAE;gBACH,UAAU,EAAE,aAAa;aAC1B;SAC4C,CAAA;QAE/C,MAAM,MAAM,GAAG,gBAAgB,CAAC;YAC9B,GAAG,EAAE,GAAG;YACR,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE,sBAAsB;YACnC,OAAO,EAAE,OAAO;SACjB,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE,sBAAsB;YACnC,OAAO,EAAE,OAAO;YAChB,SAAS,EAAE;gBACT,GAAG,EAAE;oBACH,UAAU,EAAE;wBACV,eAAe,EAAE,KAAK;wBACtB,IAAI,EAAE,UAAU;wBAChB,MAAM,EAAE,aAAa;wBACrB,UAAU,EAAE,SAAS;qBACtB;iBACF;aACF;SACF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,GAAG,GAAG;YACV,GAAG,EAAE;gBACH,iBAAiB,EAAE,QAAQ,CAAC;oBAC1B,MAAM,EAAE,gBAAgB;oBACxB,UAAU,EAAE,eAAe;iBAC5B,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;aAC9C;SAC4C,CAAA;QAE/C,MAAM,MAAM,GAAG,gBAAgB,CAAC;YAC9B,GAAG,EAAE,GAAG;YACR,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE,sBAAsB;YACnC,OAAO,EAAE,OAAO;SACjB,CAAC,CAAA;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE,sBAAsB;YACnC,OAAO,EAAE,OAAO;YAChB,SAAS,EAAE;gBACT,GAAG,EAAE;oBACH,iBAAiB,EAAE;wBACjB,eAAe,EAAE,KAAK;wBACtB,IAAI,EAAE,iBAAiB;wBACvB,MAAM,EAAE,gBAAgB;wBACxB,UAAU,EAAE,eAAe;qBAC5B;iBACF;aACF;SACF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -698,7 +698,7 @@ describe('ProxyManager', () => {
|
|
|
698
698
|
// With PathHelper.joinUrl, the URL is now valid and routes to the target server
|
|
699
699
|
// The target server returns 200, demonstrating robust URL handling
|
|
700
700
|
expect(result.status).toBe(200);
|
|
701
|
-
const body = await result.json();
|
|
701
|
+
const body = (await result.json());
|
|
702
702
|
expect(body).toStrictEqual({ message: 'ok' });
|
|
703
703
|
// No error event should be emitted since the request succeeded
|
|
704
704
|
expect(failedEvent).toBeUndefined();
|