@extk/expressive 0.5.5 → 0.6.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
@@ -22,7 +22,7 @@
22
22
 
23
23
  - **Auto-generated OpenAPI 3.1 docs** from your route definitions
24
24
  - **Structured error handling** with typed error classes and consistent JSON responses
25
- - **Winston logging** with daily file rotation and dev/prod modes
25
+ - **Bring-your-own logger** any object with `info/warn/error/debug` works
26
26
  - **Security defaults** via Helmet, safe query parsing, and morgan request logging
27
27
  - **Standardized responses** (`ApiResponse` / `ApiErrorResponse`) across your entire API
28
28
 
@@ -58,17 +58,9 @@ const {
58
58
  const swaggerDoc = swaggerBuilder()
59
59
  .withInfo({ title: 'My API', version: '1.0.0' })
60
60
  .withServers([{ url: 'http://localhost:3000' }])
61
- .get();
61
+ .build();
62
62
 
63
- // 3. Build the Express app
64
- const app = expressiveServer()
65
- .withHelmet()
66
- .withQs()
67
- .withMorgan()
68
- .withSwagger({ path: '/api-docs', doc: swaggerDoc })
69
- .get();
70
-
71
- // 4. Define routes — they auto-register in the OpenAPI spec
63
+ // 3. Define routes — they auto-register in the OpenAPI spec
72
64
  const { router, addRoute } = expressiveRouter({
73
65
  oapi: { tags: ['Users'] },
74
66
  });
@@ -89,10 +81,24 @@ addRoute(
89
81
  },
90
82
  );
91
83
 
92
- // 5. Mount the router and error handling
93
- app.use(router);
94
- app.use(getErrorHandlerMiddleware());
95
- app.use(notFoundMiddleware);
84
+ ```
85
+
86
+ > [!IMPORTANT]
87
+ > Method call order on `ServerBuilder` matters — middleware is registered in the order you chain it.
88
+
89
+ ```ts
90
+ // 4. Build the Express app
91
+ const app = expressiveServer()
92
+ .withHelmet()
93
+ .withQs()
94
+ .withMorgan()
95
+ .withRoutes(router)
96
+ .withSwagger({ path: '/api-docs', config: swaggerDoc })
97
+ .with((app) => {
98
+ app.use(getErrorHandlerMiddleware());
99
+ app.use(notFoundMiddleware);
100
+ })
101
+ .build();
96
102
 
97
103
  app.listen(3000);
98
104
  ```
@@ -211,7 +217,7 @@ const app = expressiveServer()
211
217
  .withQs()
212
218
  .withMorgan()
213
219
  .withSwagger({
214
- doc: swaggerBuilder()
220
+ config: swaggerBuilder()
215
221
  .withInfo({ title: 'My API' })
216
222
  .withServers([{ url: 'http://localhost:3000/api' }])
217
223
  .withSchemas(z.toJSONSchema(z.globalRegistry).schemas) // all Zod schemas -> OpenAPI
@@ -219,7 +225,7 @@ const app = expressiveServer()
219
225
  .withDefaultSecurity([SWG.security('auth')])
220
226
  .get(),
221
227
  })
222
- .get();
228
+ .build();
223
229
  ```
224
230
 
225
231
  **3. Reference them in routes with `SWG.jsonSchemaRef`:**
package/dist/index.d.mts CHANGED
@@ -163,17 +163,22 @@ type SwaggerConfig = {
163
163
 
164
164
  type SwaggerOptions = {
165
165
  path?: ExpressRoute;
166
- doc: SwaggerConfig;
166
+ config: SwaggerConfig;
167
167
  };
168
168
  declare class ServerBuilder {
169
169
  private app;
170
170
  private container;
171
171
  constructor(app: express__default.Express, container: Container);
172
- get(): express__default.Express;
172
+ build(): express__default.Express;
173
173
  withHelmet(options?: Readonly<HelmetOptions>): this;
174
174
  withQs(): this;
175
175
  withMorgan(format?: string, // TODO: FormatFn
176
176
  options?: Parameters<typeof morgan>[1]): this;
177
+ withRoutes(routes: ExpressRoute): this;
178
+ /**
179
+ * Helper function for fluent design
180
+ */
181
+ with(fn: (app: express__default.Express, container: Container) => void): this;
177
182
  withSwagger(swagger: SwaggerOptions, ...handlers: ExpressHandler[]): this;
178
183
  }
179
184
 
package/dist/index.d.ts CHANGED
@@ -163,17 +163,22 @@ type SwaggerConfig = {
163
163
 
164
164
  type SwaggerOptions = {
165
165
  path?: ExpressRoute;
166
- doc: SwaggerConfig;
166
+ config: SwaggerConfig;
167
167
  };
168
168
  declare class ServerBuilder {
169
169
  private app;
170
170
  private container;
171
171
  constructor(app: express__default.Express, container: Container);
172
- get(): express__default.Express;
172
+ build(): express__default.Express;
173
173
  withHelmet(options?: Readonly<HelmetOptions>): this;
174
174
  withQs(): this;
175
175
  withMorgan(format?: string, // TODO: FormatFn
176
176
  options?: Parameters<typeof morgan>[1]): this;
177
+ withRoutes(routes: ExpressRoute): this;
178
+ /**
179
+ * Helper function for fluent design
180
+ */
181
+ with(fn: (app: express__default.Express, container: Container) => void): this;
177
182
  withSwagger(swagger: SwaggerOptions, ...handlers: ExpressHandler[]): this;
178
183
  }
179
184
 
package/dist/index.js CHANGED
@@ -198,7 +198,7 @@ var ServerBuilder = class {
198
198
  this.app = app;
199
199
  this.container = container;
200
200
  }
201
- get() {
201
+ build() {
202
202
  return this.app;
203
203
  }
204
204
  withHelmet(options) {
@@ -222,9 +222,20 @@ var ServerBuilder = class {
222
222
  ));
223
223
  return this;
224
224
  }
225
+ withRoutes(routes) {
226
+ this.app.use(routes);
227
+ return this;
228
+ }
229
+ /**
230
+ * Helper function for fluent design
231
+ */
232
+ with(fn) {
233
+ fn(this.app, this.container);
234
+ return this;
235
+ }
225
236
  withSwagger(swagger, ...handlers) {
226
- this.app.use(swagger.path ?? "/api-docs", ...handlers, import_swagger_ui_express.default.serve, import_swagger_ui_express.default.setup(swagger.doc, {
227
- customSiteTitle: swagger.doc.info?.title
237
+ this.app.use(swagger.path ?? "/api-docs", ...handlers, import_swagger_ui_express.default.serve, import_swagger_ui_express.default.setup(swagger.config, {
238
+ customSiteTitle: swagger.config.info?.title
228
239
  }));
229
240
  return this;
230
241
  }
package/dist/index.mjs CHANGED
@@ -137,7 +137,7 @@ var ServerBuilder = class {
137
137
  this.app = app;
138
138
  this.container = container;
139
139
  }
140
- get() {
140
+ build() {
141
141
  return this.app;
142
142
  }
143
143
  withHelmet(options) {
@@ -161,9 +161,20 @@ var ServerBuilder = class {
161
161
  ));
162
162
  return this;
163
163
  }
164
+ withRoutes(routes) {
165
+ this.app.use(routes);
166
+ return this;
167
+ }
168
+ /**
169
+ * Helper function for fluent design
170
+ */
171
+ with(fn) {
172
+ fn(this.app, this.container);
173
+ return this;
174
+ }
164
175
  withSwagger(swagger, ...handlers) {
165
- this.app.use(swagger.path ?? "/api-docs", ...handlers, swaggerUi.serve, swaggerUi.setup(swagger.doc, {
166
- customSiteTitle: swagger.doc.info?.title
176
+ this.app.use(swagger.path ?? "/api-docs", ...handlers, swaggerUi.serve, swaggerUi.setup(swagger.config, {
177
+ customSiteTitle: swagger.config.info?.title
167
178
  }));
168
179
  return this;
169
180
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@extk/expressive",
3
- "version": "0.5.5",
3
+ "version": "0.6.1",
4
4
  "type": "commonjs",
5
5
  "publishConfig": {
6
6
  "access": "public"