snap-on-openapi 1.0.1 → 1.0.3

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.
Files changed (91) hide show
  1. package/README.md +15 -15
  2. package/dist/OpenApi.d.ts +23 -23
  3. package/dist/OpenApi.js +17 -17
  4. package/dist/OpenApi.test.d.ts +1 -0
  5. package/dist/OpenApi.test.js +418 -0
  6. package/dist/README.md +15 -15
  7. package/dist/index.d.ts +38 -38
  8. package/dist/index.js +22 -22
  9. package/dist/services/ClientGenerator/ClientGenerator.d.ts +2 -2
  10. package/dist/services/ClientGenerator/ClientGenerator.test.d.ts +1 -0
  11. package/dist/services/ClientGenerator/ClientGenerator.test.js +37 -0
  12. package/dist/services/ConfigBuilder/ConfigBuilder.d.ts +9 -9
  13. package/dist/services/ConfigBuilder/ConfigBuilder.js +1 -1
  14. package/dist/services/ConfigBuilder/ConfigBuilder.test.d.ts +1 -0
  15. package/dist/services/ConfigBuilder/ConfigBuilder.test.js +207 -0
  16. package/dist/services/ConfigBuilder/types/DefaultConfig.d.ts +9 -9
  17. package/dist/services/ConfigBuilder/types/DefaultConfig.js +6 -6
  18. package/dist/services/ConfigBuilder/types/DefaultConfig.test.d.ts +1 -0
  19. package/dist/services/ConfigBuilder/types/DefaultConfig.test.js +82 -0
  20. package/dist/services/ConfigBuilder/types/DefaultErrorMap.d.ts +7 -7
  21. package/dist/services/ConfigBuilder/types/DefaultErrorMap.js +4 -4
  22. package/dist/services/ConfigBuilder/types/DefaultRouteContextMap.d.ts +3 -3
  23. package/dist/services/ConfigBuilder/types/DefaultRouteMap.d.ts +5 -5
  24. package/dist/services/ConfigBuilder/types/DefaultRouteMap.js +2 -2
  25. package/dist/services/ConfigBuilder/types/DefaultRouteParamsMap.d.ts +2 -2
  26. package/dist/services/ConfigBuilder/types/OpenApiConstructor.d.ts +1 -1
  27. package/dist/services/DescriptionChecker/DescriptionChecker.d.ts +2 -2
  28. package/dist/services/DescriptionChecker/DescriptionChecker.js +1 -1
  29. package/dist/services/DescriptionChecker/DescriptionChecker.test.d.ts +1 -0
  30. package/dist/services/DescriptionChecker/DescriptionChecker.test.js +120 -0
  31. package/dist/services/DevelopmentUtils/DevelopmentUtils.test.d.ts +1 -0
  32. package/dist/services/DevelopmentUtils/DevelopmentUtils.test.js +10 -0
  33. package/dist/services/ExpressWrapper/ExpressWrapper.d.ts +5 -5
  34. package/dist/services/ExpressWrapper/ExpressWrapper.js +1 -1
  35. package/dist/services/ExpressWrapper/ExpressWrapper.test.d.ts +1 -0
  36. package/dist/services/ExpressWrapper/ExpressWrapper.test.js +136 -0
  37. package/dist/services/ExpressWrapper/types/ExpressApp.d.ts +1 -1
  38. package/dist/services/ExpressWrapper/types/ExpressHandler.d.ts +2 -2
  39. package/dist/services/Logger/Logger.d.ts +2 -1
  40. package/dist/services/Logger/Logger.js +4 -1
  41. package/dist/services/Logger/Logger.test.d.ts +1 -0
  42. package/dist/services/Logger/Logger.test.js +113 -0
  43. package/dist/services/RoutingFactory/RoutingFactory.d.ts +4 -4
  44. package/dist/services/SchemaGenerator/SchemaGenerator.d.ts +6 -6
  45. package/dist/services/SchemaGenerator/SchemaGenerator.js +3 -4
  46. package/dist/services/SchemaGenerator/SchemaGenerator.test.d.ts +1 -0
  47. package/dist/services/SchemaGenerator/SchemaGenerator.test.js +142 -0
  48. package/dist/services/TanstackStartWrapper/TanstackStartWrapper.d.ts +4 -4
  49. package/dist/services/TanstackStartWrapper/TanstackStartWrapper.js +1 -1
  50. package/dist/services/TanstackStartWrapper/TanstackStartWrapper.test.d.ts +1 -0
  51. package/dist/services/TanstackStartWrapper/TanstackStartWrapper.test.js +44 -0
  52. package/dist/services/TestUtils/TestUtils.d.ts +5 -5
  53. package/dist/services/TestUtils/TestUtils.js +3 -3
  54. package/dist/services/TestUtils/TestUtils.test.d.ts +1 -0
  55. package/dist/services/TestUtils/TestUtils.test.js +20 -0
  56. package/dist/services/ValidationUtils/ValidationUtils.js +3 -3
  57. package/dist/services/ValidationUtils/ValidationUtils.test.d.ts +1 -0
  58. package/dist/services/ValidationUtils/ValidationUtils.test.js +165 -0
  59. package/dist/services/ValidationUtils/transformers/stringBooleanTransformer.test.d.ts +1 -0
  60. package/dist/services/ValidationUtils/transformers/stringBooleanTransformer.test.js +19 -0
  61. package/dist/services/ValidationUtils/transformers/stringDateTransformer.test.d.ts +1 -0
  62. package/dist/services/ValidationUtils/transformers/stringDateTransformer.test.js +13 -0
  63. package/dist/services/ValidationUtils/transformers/stringNumberTransfromer.test.d.ts +1 -0
  64. package/dist/services/ValidationUtils/transformers/stringNumberTransfromer.test.js +47 -0
  65. package/dist/types/AnyRoute.d.ts +1 -1
  66. package/dist/types/InitialBuilder.d.ts +8 -8
  67. package/dist/types/Route.d.ts +2 -2
  68. package/dist/types/RouteMap.d.ts +2 -2
  69. package/dist/types/Wrappers.d.ts +3 -3
  70. package/dist/types/config/AnyConfig.d.ts +3 -3
  71. package/dist/types/config/AnyRouteConfigMap.d.ts +1 -1
  72. package/dist/types/config/Config.d.ts +10 -8
  73. package/dist/types/config/ContextParams.d.ts +2 -2
  74. package/dist/types/config/ErrorConfigMap.d.ts +1 -1
  75. package/dist/types/config/ErrorResponse.d.ts +1 -1
  76. package/dist/types/config/Info.d.ts +1 -1
  77. package/dist/types/config/RouteConfig.d.ts +1 -1
  78. package/dist/types/config/RouteConfigMap.d.ts +3 -3
  79. package/dist/types/config/RouteContextMap.d.ts +2 -2
  80. package/dist/types/config/Server.d.ts +1 -1
  81. package/dist/types/errors/BuiltInError.d.ts +2 -2
  82. package/dist/types/errors/BuiltInError.js +1 -1
  83. package/dist/types/errors/ValidationError.d.ts +2 -2
  84. package/dist/types/errors/ValidationError.js +2 -2
  85. package/dist/types/errors/responses/NotFoundErrorResponse.d.ts +1 -1
  86. package/dist/types/errors/responses/NotFoundErrorResponse.js +1 -1
  87. package/dist/types/errors/responses/UnknownErrorResponse.d.ts +1 -1
  88. package/dist/types/errors/responses/UnknownErrorResponse.js +1 -1
  89. package/dist/types/errors/responses/ValidationErrorResponse.d.ts +2 -2
  90. package/dist/types/errors/responses/ValidationErrorResponse.js +3 -3
  91. package/package.json +1 -1
package/dist/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # Strap-on OpenAPI
1
+ # Snap-On OpenAPI
2
2
 
3
3
  Bring a fully-fledged, type-checked API to your app in just 5 minutes.
4
4
 
5
- [What is Strap-On OpenAPI](#what-is-strap-on-openapi)
5
+ [What is Snap-On OpenAPI](#what-is-snap-on-openapi)
6
6
 
7
7
  [Installation](#installation)
8
8
 
@@ -21,7 +21,7 @@ Bring a fully-fledged, type-checked API to your app in just 5 minutes.
21
21
  - TypeScript client generator included
22
22
  - Since you have OpenAPI, you can generate clients for any language you want
23
23
 
24
- ## What is Strap-On OpenAPI?
24
+ ## What is Snap-On OpenAPI?
25
25
 
26
26
  OpenAPI is a standard for documenting your REST APIs. It's similar to JSDoc generators but with one major difference: it uses schemas that can be strictly typed and used for code generation.
27
27
 
@@ -35,14 +35,14 @@ Zod works so well that I stopped using classes for models and DTOs in my own pro
35
35
 
36
36
  You might have the same idea I had some time ago: why not combine Zod and OpenAPI and make our API absolutely type-checked both on the frontend and backend? That would be a blast!
37
37
 
38
- Strap-On OpenAPI is a lightweight, non-opinionated framework that allows you to do exactly that. It's highly customizable and easy to use, while providing fully type-checked context. You can forget about those "any" types that pop up here and there in your APIs.
38
+ Snap-On OpenAPI is a lightweight, non-opinionated framework that allows you to do exactly that. It's highly customizable and easy to use, while providing fully type-checked context. You can forget about those "any" types that pop up here and there in your APIs.
39
39
 
40
40
  The framework doesn't have any predefined middlewares (I don't even use such a concept) or excessive code. It has a few built-in errors and validators which I found helpful, and even those are made with the same utilities that are available to you.
41
41
 
42
- Simply put, Strap-On OpenAPI is the glue that ties together OpenAPI, Zod, and Openapi-TS. And you are in charge of how your API is shaped—that's what sets this framework apart from tools like `GraphQL` and `tRPC`.
42
+ Simply put, Snap-On OpenAPI is the glue that ties together OpenAPI, Zod, and Openapi-TS. And you are in charge of how your API is shaped—that's what sets this framework apart from tools like `GraphQL` and `tRPC`.
43
43
 
44
44
  You can check out some sample code here:
45
- https://github.com/Freddis/strap-on-openapi-samples
45
+ https://github.com/Freddis/snap-on-openapi-samples
46
46
 
47
47
  ## Disclaimer
48
48
  Configuration is a bit clunky due to the huge amount of inferred types. But trust me, when you learn the basics (and there is no advanced level—it's really lightweight) you will be able to configure your API in just 5 minutes.
@@ -70,13 +70,13 @@ export const upsertWorkouts = openApi.factory.createRoute({
70
70
  ## Installation
71
71
 
72
72
  ```shell
73
- npm install strap-on-openapi
73
+ npm install snap-on-openapi
74
74
  ```
75
75
 
76
76
  ## Quick Start
77
- The idea behind Strap-On OpenAPI is that you don't need to bother with configuration right away. It is designed to be configured as you go. Fire it up, focus on your business logic, then add errors, routes, and contexts as you go.
77
+ The idea behind Snap-On OpenAPI is that you don't need to bother with configuration right away. It is designed to be configured as you go. Fire it up, focus on your business logic, then add errors, routes, and contexts as you go.
78
78
 
79
- Right now, Strap-On OpenAPI provides quickstart wrappers for Tanstack Start and Express.
79
+ Right now, Snap-On OpenAPI provides quickstart wrappers for Tanstack Start and Express.
80
80
 
81
81
  ### Express
82
82
 
@@ -183,7 +183,7 @@ As you can see, it's not rocket science to integrate it with any framework.
183
183
 
184
184
  ## Adding Routes
185
185
 
186
- Now let's get deeper with Strap-On OpenAPI. Let's add some hot action.
186
+ Now let's get deeper with Snap-On OpenAPI. Let's add some hot action.
187
187
 
188
188
  We need to create a route and then add it to our OpenAPI instance. I recommend using a separate file for each route and one more file for the route map:
189
189
  ```typescript
@@ -229,7 +229,7 @@ export const getCars = openapi.factory.createRoute({
229
229
  Now let's create a route map:
230
230
  ```typescript
231
231
  // file: src/openapi/routes.ts
232
- import {OpenApiRouteMap, OpenApiSampleRouteType} from 'strap-on-openapi';
232
+ import {OpenApiRouteMap, OpenApiSampleRouteType} from 'snap-on-openapi';
233
233
  import {getCars} from './getCars';
234
234
 
235
235
  export const openApiRoutes: OpenApiRouteMap<OpenApiSampleRouteType> = {
@@ -313,9 +313,9 @@ And you can always write your own wrapper function to make it even less verbose
313
313
 
314
314
  ## Configuration
315
315
 
316
- Strap-On OpenAPI comes with a default configuration that covers basic errors and provides public route types. You can start with that, but eventually you will grow out of it.
316
+ Snap-On OpenAPI comes with a default configuration that covers basic errors and provides public route types. You can start with that, but eventually you will grow out of it.
317
317
 
318
- There are two ways to configure Strap-On OpenAPI:
318
+ There are two ways to configure Snap-On OpenAPI:
319
319
  1. Inferred config (recommended at the beginning)
320
320
  2. Implement OpenApiConfig interface
321
321
 
@@ -480,7 +480,7 @@ With that said, you can see that you don't have to list all possible kinds of er
480
480
 
481
481
  > [!NOTE]
482
482
  > Every error that can be thrown corresponds to one or multiple error responses. Whatever happens during API call processing, the consumer will
483
- > always receive a response. That's why Strap-On OpenAPI requires at least one error response to be defined: it has to have the default error.
483
+ > always receive a response. That's why Snap-On OpenAPI requires at least one error response to be defined: it has to have the default error.
484
484
 
485
485
  The `customizeErrors()` call will set you on the path of configuring errors. Similar to `customizeRoutes()`, you won't be able to call `create()` until you have provided everything required for the API to function properly.
486
486
 
@@ -538,7 +538,7 @@ export const openApi = OpenApi.builder.customizeErrors(
538
538
  > [!NOTE]
539
539
  > Note that the interface of `defineDefaultError` forces you to use synchronous context. It's no coincidence: errors may happen during your own error handling. This approach guarantees that whatever happens, we always have a suitable response ready.
540
540
 
541
- The last thing we need to do is write the error handler itself. Strap-On OpenAPI can't magically know what error to respond with; the best it can do is respond with the default error response.
541
+ The last thing we need to do is write the error handler itself. Snap-On OpenAPI can't magically know what error to respond with; the best it can do is respond with the default error response.
542
542
 
543
543
  Surprisingly enough, the last call related to error handling is `customizeGlobalConfig()`, which was already covered above. The reason why it's done this way is to allow you to tweak error handling when you work with `DefaultConfig`. The built-in error types are quite good, and many people may prefer to use them for a while before actually setting up their own error responses.
544
544
 
package/dist/index.d.ts CHANGED
@@ -1,39 +1,39 @@
1
1
  import 'zod-openapi/extend';
2
- export { Method as OpenApiMethod } from './enums/Methods.js';
3
- export { ErrorCode as OpenApiErrorCode } from './enums/ErrorCode.js';
4
- export { SampleRouteType as OpenApiSampleRouteType } from './enums/SampleRouteType.js';
5
- export { ValidationLocation as OpenApiValidationLocation } from './enums/ValidationLocations.js';
6
- export { ApiError as OpenApiError } from './types/errors/ApiError.js';
7
- export { ValidationError as OpenApiValidationError } from './types/errors/ValidationError.js';
8
- export { BuiltInError as OpenApiBuiltInError } from './types/errors/BuiltInError.js';
9
- export type { FieldError as OpenApiFieldError } from './types/errors/FieldError.js';
10
- export type { ErrorConfig as OpenApiErrorConfig } from './types/config/ErrorConfig.js';
11
- export type { ErrorConfigMap as OpenApiErrorConfigMap } from './types/config/ErrorConfigMap.js';
12
- export type { RouteConfig as OpenApiRouteConfig } from './types/config/RouteConfig.js';
13
- export type { RouteConfigMap as OpenApiRouteConfigMap } from './types/config/RouteConfigMap.js';
14
- export type { ContextParams as OpenApiContextParams } from './types/config/ContextParams.js';
15
- export type { ErrorResponse as OpenApiErrorResponse } from './types/config/ErrorResponse.js';
16
- export type { RouteExtraPropsMap as OpenApiRouteExtraPropsMap } from './types/config/RouteExtraPropsMap.js';
17
- export type { RouteContextMap as OpenApiRouteContextMap } from './types/config/RouteContextMap.js';
18
- export type { Config as OpenApiConfig } from './types/config/Config.js';
19
- export { DefaultConfig as OpenApiDefaultConfig } from './services/ConfigBuilder/types/DefaultConfig.js';
20
- export { DefaultErrorMap as OpenApiDefaultErrorMap } from './services/ConfigBuilder/types/DefaultErrorMap.js';
21
- export { DefaultRouteContextMap as OpenApiDefaultRouteContextMap } from './services/ConfigBuilder/types/DefaultRouteContextMap.js';
22
- export { DefaultRouteMap as OpenApiDefaultRouteMap } from './services/ConfigBuilder/types/DefaultRouteMap.js';
23
- export { DefaultRouteParamsMap as OpenApiDefaultRouteParamsMap } from './services/ConfigBuilder/types/DefaultRouteParamsMap.js';
24
- export { OpenApi } from './OpenApi.js';
25
- export type { AnyConfig as OpenApiAnyConfig } from './types/config/AnyConfig.js';
26
- export type { AnyRouteConfigMap as OpenApiAnyRouteConfigMap } from './types/config/AnyRouteConfigMap.js';
27
- export type { RouteMap as OpenApiRouteMap } from './types/RouteMap.js';
28
- export type { Route as OpenApiRoute } from './types/Route.js';
29
- export type { AnyRoute as OpenApiAnyRoute } from './types/AnyRoute.js';
30
- export type { DevelopmentUtils as OpenApiDevelopmentUtils } from './services/DevelopmentUtils/DevelopmentUtils.js';
31
- export { ClientGenerator as OpenApiClientGenerator } from './services/ClientGenerator/ClientGenerator.js';
32
- export { RoutingFactory as OpenApiRoutingFactory } from './services/RoutingFactory/RoutingFactory.js';
33
- export { SchemaGenerator as OpenApiSchemaGenerator } from './services/SchemaGenerator/SchemaGenerator.js';
34
- export { ValidationUtils as OpenApiValidationUtils } from './services/ValidationUtils/ValidationUtils.js';
35
- export { TanstackStartWrapper as OpenApiTanstackStartWrapper } from './services/TanstackStartWrapper/TanstackStartWrapper.js';
36
- export { ExpressWrapper as OpenApiExpressWrapper } from './services/ExpressWrapper/ExpressWrapper.js';
37
- export { Logger as OpenApiLogger } from './services/Logger/Logger.js';
38
- export { LogLevel as OpenApiLogLevel } from './services/Logger/types/LogLevel.js';
39
- export { ConfigBuilder as OpenApiConfigBuilder } from './services/ConfigBuilder/ConfigBuilder.js';
2
+ export { Method as OpenApiMethod } from './enums/Methods';
3
+ export { ErrorCode as OpenApiErrorCode } from './enums/ErrorCode';
4
+ export { SampleRouteType as OpenApiSampleRouteType } from './enums/SampleRouteType';
5
+ export { ValidationLocation as OpenApiValidationLocation } from './enums/ValidationLocations';
6
+ export { ApiError as OpenApiError } from './types/errors/ApiError';
7
+ export { ValidationError as OpenApiValidationError } from './types/errors/ValidationError';
8
+ export { BuiltInError as OpenApiBuiltInError } from './types/errors/BuiltInError';
9
+ export type { FieldError as OpenApiFieldError } from './types/errors/FieldError';
10
+ export type { ErrorConfig as OpenApiErrorConfig } from './types/config/ErrorConfig';
11
+ export type { ErrorConfigMap as OpenApiErrorConfigMap } from './types/config/ErrorConfigMap';
12
+ export type { RouteConfig as OpenApiRouteConfig } from './types/config/RouteConfig';
13
+ export type { RouteConfigMap as OpenApiRouteConfigMap } from './types/config/RouteConfigMap';
14
+ export type { ContextParams as OpenApiContextParams } from './types/config/ContextParams';
15
+ export type { ErrorResponse as OpenApiErrorResponse } from './types/config/ErrorResponse';
16
+ export type { RouteExtraPropsMap as OpenApiRouteExtraPropsMap } from './types/config/RouteExtraPropsMap';
17
+ export type { RouteContextMap as OpenApiRouteContextMap } from './types/config/RouteContextMap';
18
+ export type { Config as OpenApiConfig } from './types/config/Config';
19
+ export { DefaultConfig as OpenApiDefaultConfig } from './services/ConfigBuilder/types/DefaultConfig';
20
+ export { DefaultErrorMap as OpenApiDefaultErrorMap } from './services/ConfigBuilder/types/DefaultErrorMap';
21
+ export { DefaultRouteContextMap as OpenApiDefaultRouteContextMap } from './services/ConfigBuilder/types/DefaultRouteContextMap';
22
+ export { DefaultRouteMap as OpenApiDefaultRouteMap } from './services/ConfigBuilder/types/DefaultRouteMap';
23
+ export { DefaultRouteParamsMap as OpenApiDefaultRouteParamsMap } from './services/ConfigBuilder/types/DefaultRouteParamsMap';
24
+ export { OpenApi } from './OpenApi';
25
+ export type { AnyConfig as OpenApiAnyConfig } from './types/config/AnyConfig';
26
+ export type { AnyRouteConfigMap as OpenApiAnyRouteConfigMap } from './types/config/AnyRouteConfigMap';
27
+ export type { RouteMap as OpenApiRouteMap } from './types/RouteMap';
28
+ export type { Route as OpenApiRoute } from './types/Route';
29
+ export type { AnyRoute as OpenApiAnyRoute } from './types/AnyRoute';
30
+ export type { DevelopmentUtils as OpenApiDevelopmentUtils } from './services/DevelopmentUtils/DevelopmentUtils';
31
+ export { ClientGenerator as OpenApiClientGenerator } from './services/ClientGenerator/ClientGenerator';
32
+ export { RoutingFactory as OpenApiRoutingFactory } from './services/RoutingFactory/RoutingFactory';
33
+ export { SchemaGenerator as OpenApiSchemaGenerator } from './services/SchemaGenerator/SchemaGenerator';
34
+ export { ValidationUtils as OpenApiValidationUtils } from './services/ValidationUtils/ValidationUtils';
35
+ export { TanstackStartWrapper as OpenApiTanstackStartWrapper } from './services/TanstackStartWrapper/TanstackStartWrapper';
36
+ export { ExpressWrapper as OpenApiExpressWrapper } from './services/ExpressWrapper/ExpressWrapper';
37
+ export { Logger as OpenApiLogger } from './services/Logger/Logger';
38
+ export { LogLevel as OpenApiLogLevel } from './services/Logger/types/LogLevel';
39
+ export { ConfigBuilder as OpenApiConfigBuilder } from './services/ConfigBuilder/ConfigBuilder';
package/dist/index.js CHANGED
@@ -1,23 +1,23 @@
1
1
  import 'zod-openapi/extend';
2
- export { Method as OpenApiMethod } from './enums/Methods.js';
3
- export { ErrorCode as OpenApiErrorCode } from './enums/ErrorCode.js';
4
- export { SampleRouteType as OpenApiSampleRouteType } from './enums/SampleRouteType.js';
5
- export { ValidationLocation as OpenApiValidationLocation } from './enums/ValidationLocations.js';
6
- export { ApiError as OpenApiError } from './types/errors/ApiError.js';
7
- export { ValidationError as OpenApiValidationError } from './types/errors/ValidationError.js';
8
- export { BuiltInError as OpenApiBuiltInError } from './types/errors/BuiltInError.js';
9
- export { DefaultConfig as OpenApiDefaultConfig } from './services/ConfigBuilder/types/DefaultConfig.js';
10
- export { DefaultErrorMap as OpenApiDefaultErrorMap } from './services/ConfigBuilder/types/DefaultErrorMap.js';
11
- export { DefaultRouteContextMap as OpenApiDefaultRouteContextMap } from './services/ConfigBuilder/types/DefaultRouteContextMap.js';
12
- export { DefaultRouteMap as OpenApiDefaultRouteMap } from './services/ConfigBuilder/types/DefaultRouteMap.js';
13
- export { DefaultRouteParamsMap as OpenApiDefaultRouteParamsMap } from './services/ConfigBuilder/types/DefaultRouteParamsMap.js';
14
- export { OpenApi } from './OpenApi.js';
15
- export { ClientGenerator as OpenApiClientGenerator } from './services/ClientGenerator/ClientGenerator.js';
16
- export { RoutingFactory as OpenApiRoutingFactory } from './services/RoutingFactory/RoutingFactory.js';
17
- export { SchemaGenerator as OpenApiSchemaGenerator } from './services/SchemaGenerator/SchemaGenerator.js';
18
- export { ValidationUtils as OpenApiValidationUtils } from './services/ValidationUtils/ValidationUtils.js';
19
- export { TanstackStartWrapper as OpenApiTanstackStartWrapper } from './services/TanstackStartWrapper/TanstackStartWrapper.js';
20
- export { ExpressWrapper as OpenApiExpressWrapper } from './services/ExpressWrapper/ExpressWrapper.js';
21
- export { Logger as OpenApiLogger } from './services/Logger/Logger.js';
22
- export { LogLevel as OpenApiLogLevel } from './services/Logger/types/LogLevel.js';
23
- export { ConfigBuilder as OpenApiConfigBuilder } from './services/ConfigBuilder/ConfigBuilder.js';
2
+ export { Method as OpenApiMethod } from './enums/Methods';
3
+ export { ErrorCode as OpenApiErrorCode } from './enums/ErrorCode';
4
+ export { SampleRouteType as OpenApiSampleRouteType } from './enums/SampleRouteType';
5
+ export { ValidationLocation as OpenApiValidationLocation } from './enums/ValidationLocations';
6
+ export { ApiError as OpenApiError } from './types/errors/ApiError';
7
+ export { ValidationError as OpenApiValidationError } from './types/errors/ValidationError';
8
+ export { BuiltInError as OpenApiBuiltInError } from './types/errors/BuiltInError';
9
+ export { DefaultConfig as OpenApiDefaultConfig } from './services/ConfigBuilder/types/DefaultConfig';
10
+ export { DefaultErrorMap as OpenApiDefaultErrorMap } from './services/ConfigBuilder/types/DefaultErrorMap';
11
+ export { DefaultRouteContextMap as OpenApiDefaultRouteContextMap } from './services/ConfigBuilder/types/DefaultRouteContextMap';
12
+ export { DefaultRouteMap as OpenApiDefaultRouteMap } from './services/ConfigBuilder/types/DefaultRouteMap';
13
+ export { DefaultRouteParamsMap as OpenApiDefaultRouteParamsMap } from './services/ConfigBuilder/types/DefaultRouteParamsMap';
14
+ export { OpenApi } from './OpenApi';
15
+ export { ClientGenerator as OpenApiClientGenerator } from './services/ClientGenerator/ClientGenerator';
16
+ export { RoutingFactory as OpenApiRoutingFactory } from './services/RoutingFactory/RoutingFactory';
17
+ export { SchemaGenerator as OpenApiSchemaGenerator } from './services/SchemaGenerator/SchemaGenerator';
18
+ export { ValidationUtils as OpenApiValidationUtils } from './services/ValidationUtils/ValidationUtils';
19
+ export { TanstackStartWrapper as OpenApiTanstackStartWrapper } from './services/TanstackStartWrapper/TanstackStartWrapper';
20
+ export { ExpressWrapper as OpenApiExpressWrapper } from './services/ExpressWrapper/ExpressWrapper';
21
+ export { Logger as OpenApiLogger } from './services/Logger/Logger';
22
+ export { LogLevel as OpenApiLogLevel } from './services/Logger/types/LogLevel';
23
+ export { ConfigBuilder as OpenApiConfigBuilder } from './services/ConfigBuilder/ConfigBuilder';
@@ -1,6 +1,6 @@
1
1
  import { UserConfig } from '@hey-api/openapi-ts';
2
- import { OpenApi } from '../../OpenApi.js';
3
- import { AnyConfig } from '../../types/config/AnyConfig.js';
2
+ import { OpenApi } from '../../OpenApi';
3
+ import { AnyConfig } from '../../types/config/AnyConfig';
4
4
  export declare class ClientGenerator<TRouteTypes extends string, TErrorCodes extends string, TConfig extends AnyConfig<TRouteTypes, TErrorCodes>> {
5
5
  protected api: OpenApi<TRouteTypes, TErrorCodes, TConfig>;
6
6
  constructor(api: OpenApi<TRouteTypes, TErrorCodes, TConfig>);
@@ -0,0 +1,37 @@
1
+ import { afterEach, describe, expect, test } from 'vitest';
2
+ import { TestUtils } from '../TestUtils/TestUtils';
3
+ import { existsSync, rmSync } from 'fs';
4
+ import { resolve } from 'path';
5
+ describe('ClientGenerator', async () => {
6
+ const api = TestUtils.createOpenApi();
7
+ const dirs = [
8
+ 'open-api-client',
9
+ 'temp/client',
10
+ ];
11
+ afterEach(() => {
12
+ for (const dir of dirs) {
13
+ if (!existsSync(dir)) {
14
+ continue;
15
+ }
16
+ rmSync(dir, { recursive: true, force: true });
17
+ }
18
+ });
19
+ test('Happy Path', async () => {
20
+ await api.clientGenerator.generate();
21
+ const directoryCreated = await TestUtils.awaitGeneric(1000, 200, async () => {
22
+ const fileExists = existsSync(resolve('open-api-client'));
23
+ return fileExists || null;
24
+ });
25
+ expect(directoryCreated).toBe(true);
26
+ });
27
+ test('Config overrides work', async () => {
28
+ await api.clientGenerator.generate({
29
+ output: 'temp/client',
30
+ });
31
+ const directoryCreated = await TestUtils.awaitGeneric(1000, 200, async () => {
32
+ const fileExists = existsSync(resolve('temp/client'));
33
+ return fileExists || null;
34
+ });
35
+ expect(directoryCreated).toBe(true);
36
+ });
37
+ });
@@ -1,13 +1,13 @@
1
- import { ErrorConfigMap } from '../../types/config/ErrorConfigMap.js';
2
- import { Config } from '../../types/config/Config.js';
3
- import { RouteConfigMap } from '../../types/config/RouteConfigMap.js';
4
- import { OpenApi } from '../../OpenApi.js';
5
- import { AnyConfig } from '../../types/config/AnyConfig.js';
6
- import { OpenApiConstructor } from './types/OpenApiConstructor.js';
7
- import { OmitMappedField } from '../../types/config/OmitMappedField.js';
8
- import { RouteExtraPropsMap } from '../../types/config/RouteExtraPropsMap.js';
1
+ import { ErrorConfigMap } from '../../types/config/ErrorConfigMap';
2
+ import { Config } from '../../types/config/Config';
3
+ import { RouteConfigMap } from '../../types/config/RouteConfigMap';
4
+ import { OpenApi } from '../../OpenApi';
5
+ import { AnyConfig } from '../../types/config/AnyConfig';
6
+ import { OpenApiConstructor } from './types/OpenApiConstructor';
7
+ import { OmitMappedField } from '../../types/config/OmitMappedField';
8
+ import { RouteExtraPropsMap } from '../../types/config/RouteExtraPropsMap';
9
9
  import { ZodRawShape, ZodObject } from 'zod';
10
- import { RouteContextMap } from '../../types/config/RouteContextMap.js';
10
+ import { RouteContextMap } from '../../types/config/RouteContextMap';
11
11
  export declare class ConfigBuilder<TRouteTypes extends string, TErrorCodes extends string, TErrorConfigMap extends ErrorConfigMap<TErrorCodes>, TRouteParamMap extends RouteExtraPropsMap<TRouteTypes, ZodObject<ZodRawShape> | undefined>, TRouteContextMap extends RouteContextMap<TRouteTypes, TRouteParamMap>, TRouteConfigMap extends RouteConfigMap<TRouteTypes, TErrorCodes, TRouteParamMap, TRouteContextMap>, TConfig extends Config<TRouteTypes, TErrorCodes, TErrorConfigMap, TRouteParamMap, TRouteContextMap, TRouteConfigMap> = Config<TRouteTypes, TErrorCodes, TErrorConfigMap, TRouteParamMap, TRouteContextMap, TRouteConfigMap>> {
12
12
  protected x: Config<TRouteTypes, TErrorCodes, ErrorConfigMap<TErrorCodes>, RouteExtraPropsMap<TRouteTypes>, RouteContextMap<TRouteTypes, RouteExtraPropsMap<TRouteTypes>>, RouteConfigMap<TRouteTypes, TErrorCodes, RouteExtraPropsMap<TRouteTypes>, RouteContextMap<TRouteTypes, RouteExtraPropsMap<TRouteTypes>>>>;
13
13
  protected construct: OpenApiConstructor;
@@ -1,4 +1,4 @@
1
- import { DefaultConfig } from './types/DefaultConfig.js';
1
+ import { DefaultConfig } from './types/DefaultConfig';
2
2
  export class ConfigBuilder {
3
3
  x;
4
4
  construct;
@@ -0,0 +1,207 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import { ErrorCode } from '../../enums/ErrorCode';
3
+ import z from 'zod';
4
+ import { OpenApi } from '../../OpenApi';
5
+ import { Method } from '../../enums/Methods';
6
+ import { SampleRouteType } from '../../enums/SampleRouteType';
7
+ import { TestUtils } from '../TestUtils/TestUtils';
8
+ describe('ConfigBuilder', () => {
9
+ let MyRouteTypes;
10
+ (function (MyRouteTypes) {
11
+ MyRouteTypes["Public"] = "Public";
12
+ MyRouteTypes["User"] = "User";
13
+ })(MyRouteTypes || (MyRouteTypes = {}));
14
+ test('Can be created without config', async () => {
15
+ const defaultApi = OpenApi.builder.create();
16
+ const route = defaultApi.factory.createRoute({
17
+ type: SampleRouteType.Public,
18
+ method: Method.GET,
19
+ path: '/route',
20
+ description: 'Test route',
21
+ validators: {
22
+ response: z.string().openapi({ description: 'Test response' }),
23
+ },
24
+ handler: () => Promise.resolve('success'),
25
+ });
26
+ defaultApi.addRoute(route);
27
+ const req = TestUtils.createRequest('/api/something');
28
+ const res = await defaultApi.processRootRoute(req);
29
+ expect(res.body, 'Should throw error since no route is present').toEqual({
30
+ error: ErrorCode.NotFound,
31
+ });
32
+ const req2 = TestUtils.createRequest('/api/route');
33
+ const res2 = await defaultApi.processRootRoute(req2);
34
+ expect(res2.body, 'Should be able to respond correctly').toEqual('success');
35
+ });
36
+ test('Can be created with only configuring globals', async () => {
37
+ const defaultApi = OpenApi.builder.defineGlobalConfig({
38
+ basePath: '/non-default-placement',
39
+ }).create();
40
+ const route = defaultApi.factory.createRoute({
41
+ type: SampleRouteType.Public,
42
+ method: Method.GET,
43
+ path: '/route',
44
+ description: 'Test route',
45
+ validators: {
46
+ response: z.string().openapi({ description: 'Test response' }),
47
+ },
48
+ handler: () => Promise.resolve('success'),
49
+ });
50
+ defaultApi.addRoute(route);
51
+ const req = TestUtils.createRequest('/api/route');
52
+ const res = await defaultApi.processRootRoute(req);
53
+ expect(res.body, 'Should have bad response on default base path').toEqual({
54
+ error: ErrorCode.NotFound,
55
+ });
56
+ const req2 = TestUtils.createRequest('/non-default-placement/route');
57
+ const res2 = await defaultApi.processRootRoute(req2);
58
+ expect(res2.body, 'Should be able to respond on custom base path').toEqual('success');
59
+ });
60
+ test('Works Well with inferred config', async () => {
61
+ const api3 = OpenApi.builder.customizeErrors(ErrorCode).defineErrors({
62
+ [ErrorCode.UnknownError]: {
63
+ status: '500',
64
+ description: 'Unkwown Error',
65
+ responseValidator: z.object({
66
+ error: z.object({
67
+ code: z.literal(ErrorCode.UnknownError),
68
+ }),
69
+ }),
70
+ },
71
+ [ErrorCode.ValidationFailed]: {
72
+ status: '400',
73
+ description: 'Validation Failed',
74
+ responseValidator: z.object({
75
+ error: z.object({
76
+ code: z.literal(ErrorCode.ValidationFailed),
77
+ }),
78
+ }),
79
+ },
80
+ [ErrorCode.NotFound]: {
81
+ status: '404',
82
+ description: 'Route Not Found',
83
+ responseValidator: z.object({
84
+ error: z.object({
85
+ code: z.literal(ErrorCode.NotFound),
86
+ }),
87
+ }),
88
+ },
89
+ }).defineDefaultError({
90
+ code: ErrorCode.UnknownError,
91
+ body: { error: { code: ErrorCode.UnknownError } },
92
+ }).customizeRoutes(SampleRouteType).defineRouteExtraProps({
93
+ [SampleRouteType.Public]: z.object({ routeParam: z.string() }),
94
+ }).defineRouteContexts({
95
+ [SampleRouteType.Public]: (ctx) => Promise.resolve({ contextParam: ctx.route.routeParam }),
96
+ }).defineRoutes({
97
+ [SampleRouteType.Public]: {
98
+ authorization: false,
99
+ errors: {
100
+ ValidationFailed: true,
101
+ },
102
+ },
103
+ }).defineGlobalConfig({
104
+ basePath: '/api',
105
+ skipDescriptionsCheck: true,
106
+ handleError: () => {
107
+ throw new Error('Function not implemented.');
108
+ },
109
+ }).create();
110
+ const route = api3.factory.createRoute({
111
+ type: SampleRouteType.Public,
112
+ method: Method.GET,
113
+ path: '/test',
114
+ description: 'Test Route',
115
+ validators: {
116
+ response: z.string(),
117
+ },
118
+ handler: (ctx) => Promise.resolve(ctx.contextParam),
119
+ routeParam: 'myRouteParam',
120
+ });
121
+ api3.addRoutes('/', [route]);
122
+ const req = TestUtils.createRequest('/api/test', Method.GET);
123
+ const res = await api3.processRootRoute(req);
124
+ expect(res.status).toBe(200);
125
+ expect(res.body).toBe('myRouteParam');
126
+ });
127
+ test('Works Well with class-based config', async () => {
128
+ const userRouteExtraPropsvalidator = z.object({
129
+ permission: z.string(),
130
+ });
131
+ class AppErrorConfig {
132
+ [ErrorCode.UnknownError] = {
133
+ status: '500',
134
+ description: 'Unkwown Error',
135
+ responseValidator: z.object({
136
+ error: z.object({
137
+ code: z.literal(ErrorCode.UnknownError),
138
+ }),
139
+ }),
140
+ };
141
+ [ErrorCode.ValidationFailed] = {
142
+ status: '400',
143
+ description: 'Validation Failed',
144
+ responseValidator: z.object({
145
+ error: z.object({
146
+ code: z.literal(ErrorCode.ValidationFailed),
147
+ }),
148
+ }),
149
+ };
150
+ [ErrorCode.NotFound] = {
151
+ status: '404',
152
+ description: 'Route Not Found',
153
+ responseValidator: z.object({
154
+ error: z.object({
155
+ code: z.literal(ErrorCode.NotFound),
156
+ }),
157
+ }),
158
+ };
159
+ }
160
+ class AppRouteConfig {
161
+ Public = {
162
+ authorization: false,
163
+ extraProps: undefined,
164
+ contextFactory: async () => (undefined),
165
+ };
166
+ User = {
167
+ authorization: false,
168
+ contextFactory: async (ctx) => ({ permission: ctx.route.permission }),
169
+ extraProps: userRouteExtraPropsvalidator,
170
+ };
171
+ }
172
+ class AppConfig {
173
+ basePath = '/api';
174
+ routes = new AppRouteConfig();
175
+ errors = new AppErrorConfig();
176
+ defaultError = {
177
+ code: ErrorCode.UnknownError,
178
+ body: {
179
+ error: {
180
+ code: ErrorCode.UnknownError,
181
+ },
182
+ },
183
+ };
184
+ handleError() {
185
+ return this.defaultError;
186
+ }
187
+ ;
188
+ }
189
+ const api = OpenApi.builder.create(MyRouteTypes, ErrorCode, new AppConfig());
190
+ const route = api.factory.createRoute({
191
+ type: MyRouteTypes.User,
192
+ method: Method.GET,
193
+ path: '/',
194
+ description: 'Test route',
195
+ validators: {
196
+ response: z.string().openapi({ description: 'Test response' }),
197
+ },
198
+ handler: (ctx) => Promise.resolve(ctx.permission),
199
+ permission: 'My Test Permission',
200
+ });
201
+ api.addRoutes('/', [route]);
202
+ const req = TestUtils.createRequest('/api', Method.GET);
203
+ const res = await api.processRootRoute(req);
204
+ expect(res.status).toBe(200);
205
+ expect(res.body).toBe('My Test Permission');
206
+ });
207
+ });
@@ -1,12 +1,12 @@
1
- import { ErrorCode } from '../../../enums/ErrorCode.js';
2
- import { SampleRouteType } from '../../../enums/SampleRouteType.js';
3
- import { Config } from '../../../types/config/Config.js';
4
- import { ErrorResponse } from '../../../types/config/ErrorResponse.js';
5
- import { RoutePath } from '../../../types/RoutePath.js';
6
- import { DefaultErrorMap } from './DefaultErrorMap.js';
7
- import { DefaultRouteContextMap } from './DefaultRouteContextMap.js';
8
- import { DefaultRouteMap } from './DefaultRouteMap.js';
9
- import { DefaultRouteParamsMap } from './DefaultRouteParamsMap.js';
1
+ import { ErrorCode } from '../../../enums/ErrorCode';
2
+ import { SampleRouteType } from '../../../enums/SampleRouteType';
3
+ import { Config } from '../../../types/config/Config';
4
+ import { ErrorResponse } from '../../../types/config/ErrorResponse';
5
+ import { RoutePath } from '../../../types/RoutePath';
6
+ import { DefaultErrorMap } from './DefaultErrorMap';
7
+ import { DefaultRouteContextMap } from './DefaultRouteContextMap';
8
+ import { DefaultRouteMap } from './DefaultRouteMap';
9
+ import { DefaultRouteParamsMap } from './DefaultRouteParamsMap';
10
10
  export declare class DefaultConfig implements Config<SampleRouteType, ErrorCode, DefaultErrorMap, DefaultRouteParamsMap, DefaultRouteContextMap, DefaultRouteMap> {
11
11
  basePath: RoutePath;
12
12
  routes: DefaultRouteMap;
@@ -1,9 +1,9 @@
1
- import { ErrorCode } from '../../../enums/ErrorCode.js';
2
- import { ValidationLocation } from '../../../enums/ValidationLocations.js';
3
- import { BuiltInError } from '../../../types/errors/BuiltInError.js';
4
- import { ValidationError } from '../../../types/errors/ValidationError.js';
5
- import { DefaultErrorMap } from './DefaultErrorMap.js';
6
- import { DefaultRouteMap } from './DefaultRouteMap.js';
1
+ import { ErrorCode } from '../../../enums/ErrorCode';
2
+ import { ValidationLocation } from '../../../enums/ValidationLocations';
3
+ import { BuiltInError } from '../../../types/errors/BuiltInError';
4
+ import { ValidationError } from '../../../types/errors/ValidationError';
5
+ import { DefaultErrorMap } from './DefaultErrorMap';
6
+ import { DefaultRouteMap } from './DefaultRouteMap';
7
7
  export class DefaultConfig {
8
8
  basePath = '/api';
9
9
  routes = new DefaultRouteMap();