@furystack/rest-service 12.3.5 → 13.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 +38 -0
- package/esm/actions/index.d.ts +0 -1
- package/esm/actions/index.d.ts.map +1 -1
- package/esm/actions/index.js +0 -1
- package/esm/actions/index.js.map +1 -1
- package/esm/api-manager.d.ts.map +1 -1
- package/esm/api-manager.js +1 -2
- package/esm/api-manager.js.map +1 -1
- package/esm/endpoint-generators/create-get-openapi-document-action.d.ts +0 -14
- package/esm/endpoint-generators/create-get-openapi-document-action.d.ts.map +1 -1
- package/esm/endpoint-generators/create-get-openapi-document-action.js +0 -23
- package/esm/endpoint-generators/create-get-openapi-document-action.js.map +1 -1
- package/esm/endpoint-generators/with-schema-and-openapi-action.d.ts +0 -2
- package/esm/endpoint-generators/with-schema-and-openapi-action.d.ts.map +1 -1
- package/esm/openapi/generate-openapi-document.d.ts +0 -8
- package/esm/openapi/generate-openapi-document.d.ts.map +1 -1
- package/esm/openapi/generate-openapi-document.js +0 -2
- package/esm/openapi/generate-openapi-document.js.map +1 -1
- package/esm/rest-service.integration.spec.js +3 -2
- package/esm/rest-service.integration.spec.js.map +1 -1
- package/esm/validate.integration.spec.js +0 -55
- package/esm/validate.integration.spec.js.map +1 -1
- package/package.json +3 -3
- package/src/actions/index.ts +0 -1
- package/src/api-manager.ts +1 -5
- package/src/endpoint-generators/create-get-openapi-document-action.ts +0 -36
- package/src/endpoint-generators/with-schema-and-openapi-action.ts +0 -3
- package/src/openapi/generate-openapi-document.ts +0 -3
- package/src/rest-service.integration.spec.ts +3 -2
- package/src/validate.integration.spec.ts +0 -62
- package/esm/actions/login-action.spec.d.ts +0 -2
- package/esm/actions/login-action.spec.d.ts.map +0 -1
- package/esm/actions/login-action.spec.js +0 -34
- package/esm/actions/login-action.spec.js.map +0 -1
- package/esm/actions/login.d.ts +0 -19
- package/esm/actions/login.d.ts.map +0 -1
- package/esm/actions/login.js +0 -27
- package/esm/actions/login.js.map +0 -1
- package/esm/swagger/generate-swagger-json.spec.d.ts +0 -2
- package/esm/swagger/generate-swagger-json.spec.d.ts.map +0 -1
- package/esm/swagger/generate-swagger-json.spec.js +0 -215
- package/esm/swagger/generate-swagger-json.spec.js.map +0 -1
- package/src/actions/login-action.spec.ts +0 -42
- package/src/actions/login.ts +0 -32
- package/src/swagger/generate-swagger-json.spec.ts +0 -250
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
import type { ApiEndpointSchema, ParameterObject, ReferenceObject, ResponseObject } from '@furystack/rest'
|
|
2
|
-
import { describe, expect, it } from 'vitest'
|
|
3
|
-
import { generateSwaggerJsonFromApiSchema } from '../openapi/generate-openapi-document.js'
|
|
4
|
-
|
|
5
|
-
describe('generateSwaggerJsonFromApiSchema', () => {
|
|
6
|
-
it('Should generate a basic Swagger document with correct OpenAPI structure', () => {
|
|
7
|
-
const api: ApiEndpointSchema['endpoints'] = {
|
|
8
|
-
GET: {
|
|
9
|
-
'/api/test': {
|
|
10
|
-
path: '/api/test',
|
|
11
|
-
isAuthenticated: false,
|
|
12
|
-
schemaName: 'Test',
|
|
13
|
-
schema: { type: 'object', properties: { id: { type: 'string' } } },
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const result = generateSwaggerJsonFromApiSchema({ api })
|
|
19
|
-
|
|
20
|
-
// Check basic structure
|
|
21
|
-
expect(result.openapi).toBe('3.1.0')
|
|
22
|
-
expect(result.info.title).toBe('FuryStack API')
|
|
23
|
-
expect(result.info.version).toBe('1.0.0')
|
|
24
|
-
|
|
25
|
-
// Check security scheme is defined correctly for cookie-based auth
|
|
26
|
-
expect(result.components?.securitySchemes?.cookieAuth).toEqual({
|
|
27
|
-
type: 'apiKey',
|
|
28
|
-
in: 'cookie',
|
|
29
|
-
name: 'session',
|
|
30
|
-
})
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('Should convert API endpoints to OpenAPI paths correctly', () => {
|
|
34
|
-
const api: ApiEndpointSchema['endpoints'] = {
|
|
35
|
-
GET: {
|
|
36
|
-
'/api/users': {
|
|
37
|
-
path: '/api/users',
|
|
38
|
-
isAuthenticated: true,
|
|
39
|
-
schemaName: 'UserCollection',
|
|
40
|
-
schema: { type: 'array', items: { type: 'object' } },
|
|
41
|
-
},
|
|
42
|
-
'/api/users/:id': {
|
|
43
|
-
path: '/api/users/:id',
|
|
44
|
-
isAuthenticated: true,
|
|
45
|
-
schemaName: 'User',
|
|
46
|
-
schema: { type: 'object', properties: { id: { type: 'string' } } },
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const result = generateSwaggerJsonFromApiSchema({ api })
|
|
52
|
-
|
|
53
|
-
// Check paths
|
|
54
|
-
expect(result.paths?.['/api/users']).toBeDefined()
|
|
55
|
-
expect(result.paths?.['/api/users/{id}']).toBeDefined()
|
|
56
|
-
|
|
57
|
-
// Check methods
|
|
58
|
-
expect(result.paths?.['/api/users']?.get).toBeDefined()
|
|
59
|
-
expect(result.paths?.['/api/users/{id}']?.get).toBeDefined()
|
|
60
|
-
|
|
61
|
-
// Check security - should use cookieAuth for authenticated endpoints
|
|
62
|
-
expect(result.paths?.['/api/users']?.get?.security).toEqual([{ cookieAuth: [] }])
|
|
63
|
-
expect(result.paths?.['/api/users/{id}']?.get?.security).toEqual([{ cookieAuth: [] }])
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('Should extract path parameters correctly', () => {
|
|
67
|
-
const api: ApiEndpointSchema['endpoints'] = {
|
|
68
|
-
GET: {
|
|
69
|
-
'/api/users/:userId/posts/:postId': {
|
|
70
|
-
path: '/api/users/:userId/posts/:postId',
|
|
71
|
-
isAuthenticated: false,
|
|
72
|
-
schemaName: 'Post',
|
|
73
|
-
schema: { type: 'object' },
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const result = generateSwaggerJsonFromApiSchema({ api })
|
|
79
|
-
|
|
80
|
-
// Check path parameters
|
|
81
|
-
const parameters = result.paths?.['/api/users/{userId}/posts/{postId}']?.get?.parameters as ParameterObject[]
|
|
82
|
-
expect(parameters).toHaveLength(2)
|
|
83
|
-
expect(parameters?.[0].name).toBe('userId')
|
|
84
|
-
expect(parameters?.[0].in).toBe('path')
|
|
85
|
-
expect(parameters?.[0].required).toBe(true)
|
|
86
|
-
expect(parameters?.[1].name).toBe('postId')
|
|
87
|
-
expect(parameters?.[1].in).toBe('path')
|
|
88
|
-
expect(parameters?.[1].required).toBe(true)
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
it('Should handle different HTTP methods correctly', () => {
|
|
92
|
-
const api: ApiEndpointSchema['endpoints'] = {
|
|
93
|
-
GET: {
|
|
94
|
-
'/api/resource': {
|
|
95
|
-
path: '/api/resource',
|
|
96
|
-
isAuthenticated: false,
|
|
97
|
-
schemaName: 'Resource',
|
|
98
|
-
schema: { type: 'object' },
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
POST: {
|
|
102
|
-
'/api/resource': {
|
|
103
|
-
path: '/api/resource',
|
|
104
|
-
isAuthenticated: true,
|
|
105
|
-
schemaName: 'ResourceInput',
|
|
106
|
-
schema: { type: 'object' },
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
PUT: {
|
|
110
|
-
'/api/resource/:id': {
|
|
111
|
-
path: '/api/resource/:id',
|
|
112
|
-
isAuthenticated: true,
|
|
113
|
-
schemaName: 'ResourceUpdate',
|
|
114
|
-
schema: { type: 'object' },
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
DELETE: {
|
|
118
|
-
'/api/resource/:id': {
|
|
119
|
-
path: '/api/resource/:id',
|
|
120
|
-
isAuthenticated: true,
|
|
121
|
-
schemaName: 'ResourceDelete',
|
|
122
|
-
schema: { type: 'object' },
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const result = generateSwaggerJsonFromApiSchema({ api })
|
|
128
|
-
|
|
129
|
-
// Check multiple methods on same path
|
|
130
|
-
expect(result.paths?.['/api/resource'].get).toBeDefined()
|
|
131
|
-
expect(result.paths?.['/api/resource'].post).toBeDefined()
|
|
132
|
-
expect(result.paths?.['/api/resource/{id}'].put).toBeDefined()
|
|
133
|
-
expect(result.paths?.['/api/resource/{id}'].delete).toBeDefined()
|
|
134
|
-
|
|
135
|
-
// Verify security is applied correctly based on isAuthenticated
|
|
136
|
-
expect(result.paths?.['/api/resource'].get?.security).toEqual([])
|
|
137
|
-
expect(result.paths?.['/api/resource'].post?.security).toEqual([{ cookieAuth: [] }])
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
it('Should include schemas in components', () => {
|
|
141
|
-
const testSchema = {
|
|
142
|
-
type: 'object',
|
|
143
|
-
properties: {
|
|
144
|
-
id: { type: 'string' },
|
|
145
|
-
name: { type: 'string' },
|
|
146
|
-
age: { type: 'number' },
|
|
147
|
-
},
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const api: ApiEndpointSchema['endpoints'] = {
|
|
151
|
-
GET: {
|
|
152
|
-
'/api/test': {
|
|
153
|
-
path: '/api/test',
|
|
154
|
-
isAuthenticated: false,
|
|
155
|
-
schemaName: 'TestModel',
|
|
156
|
-
schema: testSchema,
|
|
157
|
-
},
|
|
158
|
-
},
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const result = generateSwaggerJsonFromApiSchema({ api })
|
|
162
|
-
|
|
163
|
-
// Check schema is included in components
|
|
164
|
-
expect(result.components?.schemas?.TestModel).toEqual(testSchema)
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
it('Should handle responses with correct status codes and content types', () => {
|
|
168
|
-
const api: ApiEndpointSchema['endpoints'] = {
|
|
169
|
-
GET: {
|
|
170
|
-
'/api/test': {
|
|
171
|
-
path: '/api/test',
|
|
172
|
-
isAuthenticated: false,
|
|
173
|
-
schemaName: 'Test',
|
|
174
|
-
schema: { type: 'object' },
|
|
175
|
-
},
|
|
176
|
-
},
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const result = generateSwaggerJsonFromApiSchema({ api })
|
|
180
|
-
|
|
181
|
-
// Check response structure
|
|
182
|
-
const responses = result.paths?.['/api/test'].get?.responses as Record<string, ResponseObject>
|
|
183
|
-
|
|
184
|
-
const response200 = responses?.['200']
|
|
185
|
-
expect(response200).toBeDefined()
|
|
186
|
-
expect(response200.description).toBe('Successful operation')
|
|
187
|
-
expect((response200.content?.['application/json']?.schema as ReferenceObject).$ref).toBe(
|
|
188
|
-
'#/components/schemas/Test',
|
|
189
|
-
)
|
|
190
|
-
expect(responses?.['401']).toBeDefined()
|
|
191
|
-
expect(responses?.['500']).toBeDefined()
|
|
192
|
-
expect(responses?.['401'].description).toBe('Unauthorized')
|
|
193
|
-
expect(responses?.['500'].description).toBe('Internal server error')
|
|
194
|
-
})
|
|
195
|
-
|
|
196
|
-
it('Should use empty path object if it does not exist - for code coverage', () => {
|
|
197
|
-
const api: ApiEndpointSchema['endpoints'] = {
|
|
198
|
-
GET: {
|
|
199
|
-
'/api/test': {
|
|
200
|
-
path: '/api/test',
|
|
201
|
-
isAuthenticated: false,
|
|
202
|
-
schemaName: 'Test',
|
|
203
|
-
schema: { type: 'object' },
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const result = generateSwaggerJsonFromApiSchema({ api })
|
|
209
|
-
|
|
210
|
-
// This test is mainly for coverage, checking that the path initialization logic works
|
|
211
|
-
expect(result.paths?.['/api/test']).toBeDefined()
|
|
212
|
-
})
|
|
213
|
-
|
|
214
|
-
it('Should handle endpoints without schemas', () => {
|
|
215
|
-
const api: ApiEndpointSchema['endpoints'] = {
|
|
216
|
-
GET: {
|
|
217
|
-
'/api/no-schema': {
|
|
218
|
-
path: '/api/no-schema',
|
|
219
|
-
isAuthenticated: false,
|
|
220
|
-
schemaName: 'EmptySchema',
|
|
221
|
-
schema: null as unknown,
|
|
222
|
-
},
|
|
223
|
-
},
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const result = generateSwaggerJsonFromApiSchema({ api })
|
|
227
|
-
|
|
228
|
-
// Should still create the path without errors
|
|
229
|
-
expect(result.paths?.['/api/no-schema']).toBeDefined()
|
|
230
|
-
expect(result.paths?.['/api/no-schema'].get).toBeDefined()
|
|
231
|
-
})
|
|
232
|
-
|
|
233
|
-
it('Should use operationId based on method and path', () => {
|
|
234
|
-
const api: ApiEndpointSchema['endpoints'] = {
|
|
235
|
-
GET: {
|
|
236
|
-
'/api/users/:id/profile': {
|
|
237
|
-
path: '/api/users/:id/profile',
|
|
238
|
-
isAuthenticated: false,
|
|
239
|
-
schemaName: 'UserProfile',
|
|
240
|
-
schema: { type: 'object' },
|
|
241
|
-
},
|
|
242
|
-
},
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const result = generateSwaggerJsonFromApiSchema({ api })
|
|
246
|
-
|
|
247
|
-
// Check operationId format
|
|
248
|
-
expect(result.paths?.['/api/users/{id}/profile'].get?.operationId).toBe('get_api_users_id_profile')
|
|
249
|
-
})
|
|
250
|
-
})
|