transit-kit 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1 +1,345 @@
1
- # declarative-server
1
+ # transit-kit
2
+
3
+ [![CI](https://github.com/D4rkr34lm/transit-kit/actions/workflows/ci.yml/badge.svg)](https://github.com/D4rkr34lm/transit-kit/actions/workflows/ci.yml)
4
+ [![Coverage Status](https://coveralls.io/repos/github/D4rkr34lm/transit-kit/badge.svg?branch=main)](https://coveralls.io/github/D4rkr34lm/transit-kit?branch=main)
5
+
6
+ A declarative TypeScript framework for building type-safe Express.js APIs with automatic OpenAPI generation.
7
+
8
+ ## Features
9
+
10
+ - 🔒 **Type-Safe**: End-to-end type safety with TypeScript and Zod validation
11
+ - 📝 **Declarative API Definition**: Define your endpoints with clear, declarative syntax
12
+ - 🔄 **Automatic Validation**: Request body and query parameter validation using Zod schemas
13
+ - 📚 **OpenAPI Generation**: Automatically generate OpenAPI documentation from your endpoint definitions
14
+ - ⚡ **Express.js Powered**: Built on top of the battle-tested Express.js framework
15
+ - 🪵 **Built-in Logging**: Request and response logging out of the box
16
+ - 🎯 **Path Parameters**: Full support for path parameters with type safety
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install transit-kit
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ### 1. Create a Server
27
+
28
+ ```typescript
29
+ import { createServer } from "transit-kit/server";
30
+
31
+ const server = createServer({
32
+ port: 3000,
33
+ inDevMode: true,
34
+ logger: true, // or pass a custom logger (console-like interface)
35
+ });
36
+ ```
37
+
38
+ ### 2. Define an API Endpoint
39
+
40
+ ```typescript
41
+ import { createApiEndpointHandler } from "transit-kit/server";
42
+ import z from "zod";
43
+
44
+ // Define a simple GET endpoint
45
+ const getUserEndpoint = createApiEndpointHandler(
46
+ {
47
+ meta: {
48
+ name: "Get User",
49
+ description: "Retrieves a user by ID",
50
+ group: "Users",
51
+ },
52
+ method: "get",
53
+ path: "/users/:userId",
54
+ responseSchemas: {
55
+ 200: {
56
+ dataType: "application/json",
57
+ dataSchema: z.object({
58
+ id: z.string(),
59
+ name: z.string(),
60
+ email: z.string().email(),
61
+ }),
62
+ },
63
+ 404: {}, // Empty response
64
+ },
65
+ },
66
+ async (request) => {
67
+ const { userId } = request.params;
68
+
69
+ // Simulate fetching user
70
+ const user = await fetchUser(userId);
71
+
72
+ if (!user) {
73
+ return {
74
+ code: 404,
75
+ };
76
+ }
77
+
78
+ return {
79
+ code: 200,
80
+ dataType: "application/json",
81
+ json: user,
82
+ };
83
+ },
84
+ );
85
+ ```
86
+
87
+ ### 3. Define an Endpoint with Request Body and Query Parameters
88
+
89
+ ```typescript
90
+ const createUserEndpoint = createApiEndpointHandler(
91
+ {
92
+ meta: {
93
+ name: "Create User",
94
+ description: "Creates a new user",
95
+ group: "Users",
96
+ },
97
+ method: "post",
98
+ path: "/users",
99
+ requestBodySchema: z.object({
100
+ name: z.string().min(1),
101
+ email: z.string().email(),
102
+ age: z.number().min(18),
103
+ }),
104
+ querySchema: z.object({
105
+ notify: z.boolean().optional(),
106
+ }),
107
+ responseSchemas: {
108
+ 201: {
109
+ dataType: "application/json",
110
+ dataSchema: z.object({
111
+ id: z.string(),
112
+ name: z.string(),
113
+ email: z.string().email(),
114
+ }),
115
+ },
116
+ 400: {
117
+ dataType: "application/json",
118
+ dataSchema: z.object({
119
+ error: z.string(),
120
+ }),
121
+ },
122
+ },
123
+ },
124
+ async (request) => {
125
+ // Request body is automatically validated and typed
126
+ const { name, email, age } = request.body;
127
+ const { notify } = request.query;
128
+
129
+ try {
130
+ const newUser = await createUser({ name, email, age });
131
+
132
+ if (notify) {
133
+ await sendNotification(email);
134
+ }
135
+
136
+ return {
137
+ code: 201,
138
+ dataType: "application/json",
139
+ json: newUser,
140
+ };
141
+ } catch (error) {
142
+ return {
143
+ code: 400,
144
+ dataType: "application/json",
145
+ json: { error: error.message },
146
+ };
147
+ }
148
+ },
149
+ );
150
+ ```
151
+
152
+ ### 4. Register Endpoints and Start Server
153
+
154
+ ```typescript
155
+ server.registerApiEndpoint(getUserEndpoint);
156
+ server.registerApiEndpoint(createUserEndpoint);
157
+
158
+ server.start();
159
+ ```
160
+
161
+ ## Response Types
162
+
163
+ ### JSON Response
164
+
165
+ For endpoints that return JSON data:
166
+
167
+ ```typescript
168
+ return {
169
+ code: 200,
170
+ dataType: "application/json",
171
+ json: { message: "Success", data: myData },
172
+ };
173
+ ```
174
+
175
+ ### Empty Response
176
+
177
+ For endpoints that return no content (e.g., 204 No Content):
178
+
179
+ ```typescript
180
+ return {
181
+ code: 204,
182
+ };
183
+ ```
184
+
185
+ ## OpenAPI Generation
186
+
187
+ Transit-kit can automatically generate OpenAPI documentation from your endpoint definitions.
188
+
189
+ ### Using the CLI
190
+
191
+ ```bash
192
+ npx transit-kit generate-openapi --output openapi.json --target ./src
193
+ ```
194
+
195
+ Options:
196
+
197
+ - `-o, --output <path>`: Output path for the generated OpenAPI document (default: `openapi.json`)
198
+ - `-t, --target <path>`: Target path to search for endpoint definitions (default: `.`)
199
+
200
+ ### Programmatic Usage
201
+
202
+ ```typescript
203
+ import { generateOpenApiDoc } from "transit-kit/cli";
204
+
205
+ const openApiDoc = await generateOpenApiDoc("./src");
206
+ ```
207
+
208
+ The generated OpenAPI document will include:
209
+
210
+ - All registered endpoints
211
+ - Request/response schemas
212
+ - Path parameters
213
+ - Query parameters
214
+ - Request body schemas
215
+ - Response schemas for all status codes
216
+
217
+ ## Configuration
218
+
219
+ ### Server Configuration
220
+
221
+ ```typescript
222
+ interface ServerConfig {
223
+ inDevMode: boolean; // Enable development mode features
224
+ port: number; // Port to listen on
225
+ logger: Logger | boolean; // Logger instance or boolean to enable/disable
226
+ }
227
+ ```
228
+
229
+ ### Custom Logger
230
+
231
+ You can provide a custom logger with a console-like interface:
232
+
233
+ ```typescript
234
+ const customLogger = {
235
+ log: (message: string) => {
236
+ /* custom logging */
237
+ },
238
+ error: (message: string) => {
239
+ /* custom error logging */
240
+ },
241
+ // ... other console methods
242
+ };
243
+
244
+ const server = createServer({
245
+ port: 3000,
246
+ inDevMode: false,
247
+ logger: customLogger,
248
+ });
249
+ ```
250
+
251
+ ## API Reference
252
+
253
+ ### `createServer(config: ServerConfig): Server`
254
+
255
+ Creates a new server instance with the specified configuration.
256
+
257
+ ### `createApiEndpointHandler(definition, handler)`
258
+
259
+ Creates an API endpoint handler with type-safe request/response handling.
260
+
261
+ **Definition properties:**
262
+
263
+ - `meta`: Metadata about the endpoint (name, description, group)
264
+ - `method`: HTTP method (`get`, `post`, `put`, `patch`, `delete`)
265
+ - `path`: Express-style path with optional parameters (e.g., `/users/:userId`)
266
+ - `requestBodySchema`: (Optional) Zod schema for request body validation
267
+ - `querySchema`: (Optional) Zod schema for query parameter validation
268
+ - `responseSchemas`: Map of status codes to response schemas
269
+
270
+ ### `server.registerApiEndpoint(endpoint)`
271
+
272
+ Registers an endpoint with the server.
273
+
274
+ ### `server.start()`
275
+
276
+ Starts the Express server on the configured port.
277
+
278
+ ## Examples
279
+
280
+ ### Complete Example
281
+
282
+ ```typescript
283
+ import { createServer, createApiEndpointHandler } from "transit-kit/server";
284
+ import z from "zod";
285
+
286
+ // Create server
287
+ const server = createServer({
288
+ port: 3000,
289
+ inDevMode: true,
290
+ logger: true,
291
+ });
292
+
293
+ // Define endpoints
294
+ const listUsersEndpoint = createApiEndpointHandler(
295
+ {
296
+ meta: {
297
+ name: "List Users",
298
+ description: "Get a list of all users",
299
+ group: "Users",
300
+ },
301
+ method: "get",
302
+ path: "/users",
303
+ querySchema: z.object({
304
+ page: z.number().optional(),
305
+ limit: z.number().optional(),
306
+ }),
307
+ responseSchemas: {
308
+ 200: {
309
+ dataType: "application/json",
310
+ dataSchema: z.array(
311
+ z.object({
312
+ id: z.string(),
313
+ name: z.string(),
314
+ }),
315
+ ),
316
+ },
317
+ },
318
+ },
319
+ async (request) => {
320
+ const { page = 1, limit = 10 } = request.query;
321
+ const users = await fetchUsers(page, limit);
322
+
323
+ return {
324
+ code: 200,
325
+ dataType: "application/json",
326
+ json: users,
327
+ };
328
+ },
329
+ );
330
+
331
+ server.registerApiEndpoint(listUsersEndpoint);
332
+ server.start();
333
+ ```
334
+
335
+ ## License
336
+
337
+ MIT
338
+
339
+ ## Contributing
340
+
341
+ Contributions are welcome! Please feel free to submit a Pull Request.
342
+
343
+ ## Author
344
+
345
+ D4rkr34lm
@@ -1,2 +1,11 @@
1
+ import { HttpMethod } from "../server/constants/HttpMethods";
2
+ import { ApiEndpointDefinition } from "../server/handlers/api/EndpointDefinition";
3
+ import { GenericResponseSchemaMap } from "../server/handlers/api/responses";
4
+ import { ZodType } from "zod";
1
5
  import { OpenAPIV3 } from "openapi-types";
6
+ declare function translateToOpenAPIPathItem(definition: ApiEndpointDefinition<string, HttpMethod, ZodType | undefined, ZodType | undefined, GenericResponseSchemaMap>): [string, OpenAPIV3.PathItemObject];
2
7
  export declare function generateOpenApiDoc(targetPath: string): Promise<OpenAPIV3.Document<{}>>;
8
+ export declare const __TEST_EXPORTS: {
9
+ translateToOpenAPIPathItem: typeof translateToOpenAPIPathItem;
10
+ };
11
+ export {};
@@ -128,3 +128,6 @@ export async function generateOpenApiDoc(targetPath) {
128
128
  throw new Error("The specified module does not export a valid server instance.");
129
129
  }
130
130
  }
131
+ export const __TEST_EXPORTS = {
132
+ translateToOpenAPIPathItem,
133
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,65 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import z from "zod";
3
+ import { createApiEndpointHandler } from "../server";
4
+ import { __TEST_EXPORTS } from "./generateOpenApi";
5
+ const { translateToOpenAPIPathItem } = __TEST_EXPORTS;
6
+ describe("translateToOpenAPIPathItem", () => {
7
+ it("should translate endpoint definitions to OpenAPI path items", () => {
8
+ const { definition } = createApiEndpointHandler({
9
+ method: "get",
10
+ path: "/users/:id",
11
+ meta: {
12
+ name: "getUser",
13
+ description: "Retrieve a user by ID",
14
+ group: "User",
15
+ },
16
+ responseSchemas: {
17
+ 200: {
18
+ dataType: "application/json",
19
+ dataSchema: z.string(),
20
+ },
21
+ },
22
+ }, async (req) => {
23
+ return {
24
+ code: 200,
25
+ dataType: "application/json",
26
+ json: req.params.id,
27
+ };
28
+ });
29
+ const [path, pathItem] = translateToOpenAPIPathItem(definition);
30
+ const expectedPath = "/users/{id}";
31
+ const expectedSchema = {
32
+ $schema: "https://json-schema.org/draft/2020-12/schema",
33
+ type: "string",
34
+ };
35
+ const expectedPathItem = {
36
+ get: {
37
+ operationId: "getUser",
38
+ summary: "Retrieve a user by ID",
39
+ tags: ["User"],
40
+ description: "Retrieve a user by ID",
41
+ parameters: [
42
+ {
43
+ description: "Path parameter :id",
44
+ name: "id",
45
+ in: "path",
46
+ required: true,
47
+ schema: { type: "string" },
48
+ },
49
+ ],
50
+ responses: {
51
+ "200": {
52
+ description: "Response for status code 200",
53
+ content: {
54
+ "application/json": {
55
+ schema: expectedSchema,
56
+ },
57
+ },
58
+ },
59
+ },
60
+ },
61
+ };
62
+ expect(path).toBe(expectedPath);
63
+ expect(pathItem).toEqual(expectedPathItem);
64
+ });
65
+ });
@@ -0,0 +1,9 @@
1
+ import z from "zod";
2
+ import { HttpMethod } from "../../constants/HttpMethods";
3
+ import { ApiEndpointDefinition } from "./EndpointDefinition";
4
+ import { HandlerForDefinition } from "./HandlerFromDefinition";
5
+ import { GenericResponseSchemaMap } from "./responses";
6
+ export interface ApiEndpoint<Path extends string = string, Method extends HttpMethod = HttpMethod, RequestBody extends z.ZodType | undefined = undefined | z.ZodType, Query extends z.ZodType | undefined = undefined | z.ZodType, ResponseMap extends GenericResponseSchemaMap = GenericResponseSchemaMap, Handler extends HandlerForDefinition<Path, RequestBody, Query, ResponseMap> = HandlerForDefinition<Path, RequestBody, Query, ResponseMap>> {
7
+ definition: ApiEndpointDefinition<Path, Method, RequestBody, Query, ResponseMap>;
8
+ handler: Handler;
9
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -6,7 +6,7 @@ export interface ApiEndpointMeta {
6
6
  group: string;
7
7
  description: string;
8
8
  }
9
- export type ApiEndpointDefinition<Path extends string, Method extends HttpMethod, RequestBody extends z.ZodType | undefined, Query extends z.ZodType | undefined, ResponseMap extends GenericResponseSchemaMap> = {
9
+ export type ApiEndpointDefinition<Path extends string = string, Method extends HttpMethod = HttpMethod, RequestBody extends z.ZodType | undefined = z.ZodType | undefined, Query extends z.ZodType | undefined = z.ZodType | undefined, ResponseMap extends GenericResponseSchemaMap = GenericResponseSchemaMap> = {
10
10
  meta: ApiEndpointMeta;
11
11
  path: Path;
12
12
  method: Method;
@@ -4,8 +4,8 @@ import { Prettify } from "../../utils/types";
4
4
  import { ApiEndpointHandler } from "./EndpointHandler";
5
5
  import { ExtractPathParams } from "./PathParameters";
6
6
  import { EmptyResponse, EmptyResponseSchema } from "./responses/emptyResponse";
7
- import { GenericResponseSchemaMap } from "./responses/index";
7
+ import { GenericResponse, GenericResponseSchemaMap } from "./responses/index";
8
8
  import { JsonResponseSchema, JsonResponseSchemaToResponseType } from "./responses/jsonResponse";
9
- export type HandlerForDefinition<Path extends string, RequestBody extends z.ZodType | undefined, Query extends z.ZodType | undefined, ResponsesMap extends GenericResponseSchemaMap> = ApiEndpointHandler<ExtractPathParams<Path>, RequestBody extends undefined ? undefined : z.infer<RequestBody>, Query extends undefined ? undefined : z.infer<Query>, Prettify<{
10
- [K in keyof ResponsesMap]: K extends HttpStatusCode ? ResponsesMap[K] extends JsonResponseSchema ? JsonResponseSchemaToResponseType<K, ResponsesMap[K]> : ResponsesMap[K] extends EmptyResponseSchema ? EmptyResponse<K> : never : never;
11
- }[keyof ResponsesMap]>>;
9
+ export type HandlerForDefinition<Path extends string, RequestBody extends z.ZodType | undefined, Query extends z.ZodType | undefined, ResponsesMap extends GenericResponseSchemaMap> = ApiEndpointHandler<ExtractPathParams<Path>, RequestBody extends undefined ? undefined : z.infer<RequestBody>, Query extends undefined ? undefined : z.infer<Query>, Exclude<Prettify<{
10
+ [K in keyof ResponsesMap]: K extends HttpStatusCode ? ResponsesMap[K] extends JsonResponseSchema ? JsonResponseSchemaToResponseType<K, ResponsesMap[K]> : ResponsesMap[K] extends EmptyResponseSchema ? EmptyResponse<K> : ResponsesMap[K] extends undefined ? never : GenericResponse : never;
11
+ }[keyof ResponsesMap]>, undefined>>;
@@ -1,11 +1,19 @@
1
1
  import z from "zod";
2
2
  import { HttpMethod } from "../../constants/HttpMethods";
3
+ import { Prettify } from "../../utils/types";
3
4
  import { ApiEndpointDefinition } from "./EndpointDefinition";
4
5
  import { ApiEndpointHandler } from "./EndpointHandler";
5
6
  import { HandlerForDefinition } from "./HandlerFromDefinition";
6
7
  import { GenericResponse, GenericResponseSchemaMap } from "./responses";
7
- export declare function createApiEndpointHandler<const ResponsesMap extends GenericResponseSchemaMap, const Path extends string, const Method extends HttpMethod, const RequestBody extends z.ZodType | undefined = undefined, const Query extends z.ZodType | undefined = undefined>(definition: ApiEndpointDefinition<Path, Method, RequestBody, Query, ResponsesMap>, handler: HandlerForDefinition<Path, RequestBody, Query, ResponsesMap>): {
8
- definition: ApiEndpointDefinition<Path, Method, RequestBody, Query, ResponsesMap>;
8
+ export declare function createApiEndpointHandler<const ResponsesMap extends GenericResponseSchemaMap, const Path extends string, const Method extends HttpMethod, const RequestBody extends z.ZodType | undefined = undefined, const Query extends z.ZodType | undefined = undefined>(definition: Prettify<ApiEndpointDefinition<Path, Method, RequestBody, Query, ResponsesMap>>, handler: HandlerForDefinition<Path, RequestBody, Query, ResponsesMap>): {
9
+ definition: {
10
+ meta: import("./EndpointDefinition").ApiEndpointMeta;
11
+ path: Path;
12
+ method: Method;
13
+ requestBodySchema?: RequestBody | undefined;
14
+ querySchema?: Query | undefined;
15
+ responseSchemas: ResponsesMap;
16
+ };
9
17
  handler: HandlerForDefinition<Path, RequestBody, Query, ResponsesMap>;
10
18
  };
11
- export declare function buildApiEndpointHandler(handler: ApiEndpointHandler<Record<string, string>, unknown, unknown, GenericResponse>): import("express").RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
19
+ export declare function buildApiEndpointHandler<Handler extends ApiEndpointHandler<Record<string, string>, unknown, unknown, GenericResponse>>(handler: Handler): import("express").RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
@@ -2,6 +2,7 @@ import { describe, it } from "vitest";
2
2
  import { createServer } from "../../server";
3
3
  import { createApiEndpointHandler } from "./createApiHandler";
4
4
  import testRequest from "supertest";
5
+ import z from "zod";
5
6
  describe("createApiHandler", () => {
6
7
  it("can create an API handler", () => {
7
8
  const endpoint = createApiEndpointHandler({
@@ -12,6 +13,7 @@ describe("createApiHandler", () => {
12
13
  },
13
14
  method: "get",
14
15
  path: "/test",
16
+ requestBodySchema: z.string(),
15
17
  responseSchemas: {
16
18
  200: {},
17
19
  },
@@ -24,8 +26,8 @@ describe("createApiHandler", () => {
24
26
  inDevMode: true,
25
27
  port: 3000,
26
28
  logger: false,
27
- endpoints: [endpoint],
28
29
  });
30
+ server.registerApiEndpoint(endpoint);
29
31
  testRequest(server.expressApp).get("/test").expect(200);
30
32
  });
31
33
  });
@@ -1,23 +1,20 @@
1
1
  import { Application } from "express";
2
- import z from "zod";
3
- import { HttpMethod } from "./constants/HttpMethods";
4
2
  import { ApiEndpointDefinition } from "./handlers/api/EndpointDefinition";
5
- import { ApiEndpointHandler } from "./handlers/api/EndpointHandler";
6
- import { GenericResponse, GenericResponseSchemaMap } from "./handlers/api/responses";
3
+ import { HandlerForDefinition } from "./handlers/api/HandlerFromDefinition";
7
4
  import { Logger } from "./utils/logging";
8
5
  export interface ServerConfig {
9
6
  inDevMode: boolean;
10
7
  port: number;
11
8
  logger: Logger | boolean;
12
- endpoints: Array<{
13
- handler: ApiEndpointHandler<Record<string, string>, any, any, GenericResponse>;
14
- definition: ApiEndpointDefinition<string, HttpMethod, z.ZodType | undefined, z.ZodType | undefined, GenericResponseSchemaMap>;
15
- }>;
16
9
  }
17
10
  export interface Server {
18
11
  expressApp: Application;
19
12
  logger: Logger | boolean;
20
- endpointDefinitions: ApiEndpointDefinition<string, HttpMethod, z.ZodType | undefined, z.ZodType | undefined, GenericResponseSchemaMap>[];
13
+ endpointDefinitions: ApiEndpointDefinition[];
14
+ registerApiEndpoint<Definition extends ApiEndpointDefinition>({ definition, handler, }: {
15
+ definition: Definition;
16
+ handler: HandlerForDefinition<Definition["path"], Definition["requestBodySchema"], Definition["querySchema"], Definition["responseSchemas"]>;
17
+ }): void;
21
18
  start: () => void;
22
19
  }
23
20
  export declare function createServer(config: ServerConfig): Server;
@@ -5,20 +5,21 @@ import { buildRequestLogger, buildResponseLogger } from "./middleware/logging";
5
5
  import { buildBodyValidatorMiddleware, buildQueryValidatorMiddleware, } from "./middleware/validation";
6
6
  import { NoOpLogger } from "./utils/logging";
7
7
  import { hasNoValue, hasValue } from "./utils/typeGuards";
8
- function registerApiEndpoint(expressApp, endpointDefinition, endpointHandler) {
8
+ function registerApiEndpoint(expressApp, endpoint) {
9
+ const { definition, handler } = endpoint;
9
10
  const handlerStack = [
10
- hasValue(endpointDefinition.querySchema)
11
- ? buildQueryValidatorMiddleware(endpointDefinition.querySchema)
11
+ hasValue(definition.querySchema)
12
+ ? buildQueryValidatorMiddleware(definition.querySchema)
12
13
  : null,
13
- hasValue(endpointDefinition.requestBodySchema)
14
- ? buildBodyValidatorMiddleware(endpointDefinition.requestBodySchema)
14
+ hasValue(definition.requestBodySchema)
15
+ ? buildBodyValidatorMiddleware(definition.requestBodySchema)
15
16
  : null,
16
- buildApiEndpointHandler(endpointHandler),
17
+ buildApiEndpointHandler(handler),
17
18
  ].filter(hasValue);
18
- expressApp[endpointDefinition.method](endpointDefinition.path, handlerStack);
19
+ expressApp[definition.method](definition.path, handlerStack);
19
20
  }
20
21
  export function createServer(config) {
21
- const { port, inDevMode, endpoints } = config;
22
+ const { port, inDevMode } = config;
22
23
  const logger = config.logger === true
23
24
  ? console
24
25
  : config.logger === false || hasNoValue(config.logger)
@@ -30,14 +31,14 @@ export function createServer(config) {
30
31
  app.use(cookieParser());
31
32
  app.use(buildRequestLogger(logger, inDevMode));
32
33
  app.use(buildResponseLogger(logger, inDevMode));
33
- endpoints.forEach(({ definition, handler }) => {
34
- registerApiEndpoint(app, definition, handler);
35
- });
36
34
  return {
37
35
  expressApp: app,
38
36
  logger: logger,
39
- endpointDefinitions: endpoints.map((e) => e.definition),
40
- start: () => {
37
+ endpointDefinitions: [],
38
+ registerApiEndpoint(endpoint) {
39
+ registerApiEndpoint(app, endpoint);
40
+ },
41
+ start() {
41
42
  app.listen(port);
42
43
  },
43
44
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "transit-kit",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "A declarative TypeScript framework for building type-safe Express.js APIs with automatic OpenAPI generation",
5
5
  "keywords": [
6
6
  "express",
@@ -28,9 +28,9 @@
28
28
  ],
29
29
  "exports": {
30
30
  "./server": {
31
+ "types": "./dist/server/server.d.ts",
31
32
  "import": "./dist/server/index.js",
32
- "require": "./dist/server/index.js",
33
- "types": "./dist/server/server.d.ts"
33
+ "require": "./dist/server/index.js"
34
34
  }
35
35
  },
36
36
  "bin": "./dist/cli/cli.js",