@extk/expressive 0.10.1 → 0.11.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/dist/index.d.mts CHANGED
@@ -225,11 +225,12 @@ declare const SWG: {
225
225
  };
226
226
 
227
227
  type SwaggerRef = {
228
- doc: SwaggerConfig | null;
228
+ doc?: SwaggerConfig | null;
229
+ bootstrapOptions?: SwaggerBootstrapOpts | null;
229
230
  };
230
- type ExpressiveSwaggerOptions = {
231
- path: ExpressRoute;
231
+ type SwaggerBootstrapOpts = {
232
232
  enabled?: boolean;
233
+ configure?: (builder: SwaggerBuilder) => void;
233
234
  uiOpts?: SwaggerUiOptions;
234
235
  options?: SwaggerOptions;
235
236
  customCss?: string;
@@ -237,6 +238,9 @@ type ExpressiveSwaggerOptions = {
237
238
  swaggerUrl?: string;
238
239
  customSiteTitle?: string;
239
240
  };
241
+ type BuildExpressiveOpts = {
242
+ swagger?: SwaggerBootstrapOpts;
243
+ };
240
244
  declare class ServerBuilder {
241
245
  private app;
242
246
  private container;
@@ -250,7 +254,7 @@ declare class ServerBuilder {
250
254
  * Helper function for fluent design
251
255
  */
252
256
  with(fn: (app: express__default.Express, container: Container) => void): this;
253
- withSwagger(configure: (builder: SwaggerBuilder) => void, opts: ExpressiveSwaggerOptions, ...handlers: ExpressHandler[]): this;
257
+ withSwagger(path?: string, ...handlers: ExpressHandler[]): this;
254
258
  }
255
259
 
256
260
  declare class ApiError extends Error {
@@ -324,7 +328,7 @@ declare class ApiResponse<T = undefined> {
324
328
  constructor(result?: T);
325
329
  }
326
330
 
327
- declare function bootstrap(container: Container): {
331
+ declare function bootstrap(container: Container, opts?: BuildExpressiveOpts): {
328
332
  silently: (fn: () => Promise<void> | void) => Promise<void>;
329
333
  getGlobalNotFoundMiddleware: (content?: string) => (_req: express.Request, res: express.Response, _next: express.NextFunction) => void;
330
334
  getApiNotFoundMiddleware: () => (req: express.Request, res: express.Response, _next: express.NextFunction) => void;
package/dist/index.d.ts CHANGED
@@ -225,11 +225,12 @@ declare const SWG: {
225
225
  };
226
226
 
227
227
  type SwaggerRef = {
228
- doc: SwaggerConfig | null;
228
+ doc?: SwaggerConfig | null;
229
+ bootstrapOptions?: SwaggerBootstrapOpts | null;
229
230
  };
230
- type ExpressiveSwaggerOptions = {
231
- path: ExpressRoute;
231
+ type SwaggerBootstrapOpts = {
232
232
  enabled?: boolean;
233
+ configure?: (builder: SwaggerBuilder) => void;
233
234
  uiOpts?: SwaggerUiOptions;
234
235
  options?: SwaggerOptions;
235
236
  customCss?: string;
@@ -237,6 +238,9 @@ type ExpressiveSwaggerOptions = {
237
238
  swaggerUrl?: string;
238
239
  customSiteTitle?: string;
239
240
  };
241
+ type BuildExpressiveOpts = {
242
+ swagger?: SwaggerBootstrapOpts;
243
+ };
240
244
  declare class ServerBuilder {
241
245
  private app;
242
246
  private container;
@@ -250,7 +254,7 @@ declare class ServerBuilder {
250
254
  * Helper function for fluent design
251
255
  */
252
256
  with(fn: (app: express__default.Express, container: Container) => void): this;
253
- withSwagger(configure: (builder: SwaggerBuilder) => void, opts: ExpressiveSwaggerOptions, ...handlers: ExpressHandler[]): this;
257
+ withSwagger(path?: string, ...handlers: ExpressHandler[]): this;
254
258
  }
255
259
 
256
260
  declare class ApiError extends Error {
@@ -324,7 +328,7 @@ declare class ApiResponse<T = undefined> {
324
328
  constructor(result?: T);
325
329
  }
326
330
 
327
- declare function bootstrap(container: Container): {
331
+ declare function bootstrap(container: Container, opts?: BuildExpressiveOpts): {
328
332
  silently: (fn: () => Promise<void> | void) => Promise<void>;
329
333
  getGlobalNotFoundMiddleware: (content?: string) => (_req: express.Request, res: express.Response, _next: express.NextFunction) => void;
330
334
  getApiNotFoundMiddleware: () => (req: express.Request, res: express.Response, _next: express.NextFunction) => void;
package/dist/index.js CHANGED
@@ -213,7 +213,10 @@ var ServerBuilder = class {
213
213
  this.swaggerRef = swaggerRef;
214
214
  }
215
215
  build() {
216
- this.swaggerRef.doc = null;
216
+ if (this.swaggerRef) {
217
+ this.swaggerRef.doc = null;
218
+ this.swaggerRef.bootstrapOptions = null;
219
+ }
217
220
  return this.app;
218
221
  }
219
222
  withHelmet(options) {
@@ -240,23 +243,30 @@ var ServerBuilder = class {
240
243
  fn(this.app, this.container);
241
244
  return this;
242
245
  }
243
- withSwagger(configure, opts, ...handlers) {
244
- if (opts.enabled === false) return this;
245
- const config = this.swaggerRef.doc;
246
- if (!config) throw new Error("withSwagger must be called before build()");
247
- configure(new SwaggerBuilder(config));
248
- const { path: path2, uiOpts, options, customCss, customfavIcon, swaggerUrl, customSiteTitle } = opts;
249
- const uiOptsWithDefaults = {
250
- customSiteTitle: config.info?.title,
251
- ...uiOpts
252
- };
246
+ withSwagger(path2 = "/api-docs", ...handlers) {
247
+ if (!this.swaggerRef || !this.swaggerRef.doc) {
248
+ return this;
249
+ }
250
+ const doc = this.swaggerRef.doc;
251
+ const {
252
+ configure,
253
+ uiOpts,
254
+ options,
255
+ customCss,
256
+ customfavIcon,
257
+ swaggerUrl,
258
+ customSiteTitle
259
+ } = this.swaggerRef.bootstrapOptions ?? {};
260
+ if (configure) {
261
+ configure(new SwaggerBuilder(doc));
262
+ }
253
263
  this.app.use(
254
264
  path2,
255
265
  ...handlers,
256
266
  import_swagger_ui_express.default.serve,
257
267
  import_swagger_ui_express.default.setup(
258
- config,
259
- uiOptsWithDefaults,
268
+ doc,
269
+ { customSiteTitle: doc.info?.title, ...uiOpts },
260
270
  options,
261
271
  customCss,
262
272
  customfavIcon,
@@ -267,14 +277,11 @@ var ServerBuilder = class {
267
277
  return this;
268
278
  }
269
279
  };
270
- function buildExpressive(container) {
271
- const swaggerRef = {
272
- doc: {
273
- openapi: "3.1.0",
274
- info: {},
275
- paths: {},
276
- components: {}
277
- }
280
+ function buildExpressive(container, opts) {
281
+ const swaggerBootstrapOpts = opts?.swagger;
282
+ const swaggerRef = !swaggerBootstrapOpts || swaggerBootstrapOpts.enabled === false ? {} : {
283
+ doc: { openapi: "3.1.0", info: {}, paths: {}, components: {} },
284
+ bootstrapOptions: swaggerBootstrapOpts
278
285
  };
279
286
  return {
280
287
  expressiveServer(configs) {
@@ -287,42 +294,42 @@ function buildExpressive(container) {
287
294
  router,
288
295
  addRoute(context, ...handlers) {
289
296
  router[context.method](context.path, ...handlers);
290
- const {
291
- pathOverride,
292
- pathParameters,
293
- headerParameters,
294
- queryParameters,
295
- ...pathItemConfig
296
- } = context.oapi || {};
297
- const route = pathOverride ?? convertExpressPath(context.path);
298
- const pathItem = {
299
- // -- defaults --
300
- responses: {
301
- // has to be defined or else responses are not documented... ¯\_(ツ)_/¯
302
- "200": { description: "OK" },
303
- "201": { description: "Created" },
304
- "204": { description: "No Content" },
305
- "400": { description: "Bad Request" },
306
- "401": { description: "User Unauthorized" },
307
- "403": { description: "Forbidden" },
308
- "500": { description: "Internal Server Error" }
309
- },
310
- // -- group defaults --
311
- ...configs?.oapi || {},
312
- // -- overrides --
313
- ...pathItemConfig || {},
314
- parameters: [
315
- // ...(contract.pathParameters || []),
316
- ...headerParameters || [],
317
- ...queryParameters || []
318
- ]
319
- };
320
- if (pathParameters?.length) {
321
- pathItem.parameters.push(...pathParameters);
322
- } else {
323
- pathItem.parameters.push(...tryParsePathParameters(route));
324
- }
325
- if (swaggerRef.doc) {
297
+ if (swaggerRef?.doc) {
298
+ const {
299
+ pathOverride,
300
+ pathParameters,
301
+ headerParameters,
302
+ queryParameters,
303
+ ...pathItemConfig
304
+ } = context.oapi || {};
305
+ const route = pathOverride ?? convertExpressPath(context.path);
306
+ const pathItem = {
307
+ // -- defaults --
308
+ responses: {
309
+ // has to be defined or else responses are not documented... ¯\_(ツ)_/¯
310
+ "200": { description: "OK" },
311
+ "201": { description: "Created" },
312
+ "204": { description: "No Content" },
313
+ "400": { description: "Bad Request" },
314
+ "401": { description: "User Unauthorized" },
315
+ "403": { description: "Forbidden" },
316
+ "500": { description: "Internal Server Error" }
317
+ },
318
+ // -- group defaults --
319
+ ...configs?.oapi || {},
320
+ // -- overrides --
321
+ ...pathItemConfig || {},
322
+ parameters: [
323
+ // ...(contract.pathParameters || []),
324
+ ...headerParameters || [],
325
+ ...queryParameters || []
326
+ ]
327
+ };
328
+ if (pathParameters?.length) {
329
+ pathItem.parameters.push(...pathParameters);
330
+ } else {
331
+ pathItem.parameters.push(...tryParsePathParameters(route));
332
+ }
326
333
  if (!swaggerRef.doc.paths[route]) {
327
334
  swaggerRef.doc.paths[route] = {};
328
335
  }
@@ -564,9 +571,9 @@ var ApiResponse = class {
564
571
  };
565
572
 
566
573
  // src/index.ts
567
- function bootstrap(container) {
574
+ function bootstrap(container, opts) {
568
575
  return {
569
- ...buildExpressive(container),
576
+ ...buildExpressive(container, opts),
570
577
  ...buildMiddleware(container),
571
578
  silently: async (fn) => {
572
579
  try {
package/dist/index.mjs CHANGED
@@ -152,7 +152,10 @@ var ServerBuilder = class {
152
152
  this.swaggerRef = swaggerRef;
153
153
  }
154
154
  build() {
155
- this.swaggerRef.doc = null;
155
+ if (this.swaggerRef) {
156
+ this.swaggerRef.doc = null;
157
+ this.swaggerRef.bootstrapOptions = null;
158
+ }
156
159
  return this.app;
157
160
  }
158
161
  withHelmet(options) {
@@ -179,23 +182,30 @@ var ServerBuilder = class {
179
182
  fn(this.app, this.container);
180
183
  return this;
181
184
  }
182
- withSwagger(configure, opts, ...handlers) {
183
- if (opts.enabled === false) return this;
184
- const config = this.swaggerRef.doc;
185
- if (!config) throw new Error("withSwagger must be called before build()");
186
- configure(new SwaggerBuilder(config));
187
- const { path: path2, uiOpts, options, customCss, customfavIcon, swaggerUrl, customSiteTitle } = opts;
188
- const uiOptsWithDefaults = {
189
- customSiteTitle: config.info?.title,
190
- ...uiOpts
191
- };
185
+ withSwagger(path2 = "/api-docs", ...handlers) {
186
+ if (!this.swaggerRef || !this.swaggerRef.doc) {
187
+ return this;
188
+ }
189
+ const doc = this.swaggerRef.doc;
190
+ const {
191
+ configure,
192
+ uiOpts,
193
+ options,
194
+ customCss,
195
+ customfavIcon,
196
+ swaggerUrl,
197
+ customSiteTitle
198
+ } = this.swaggerRef.bootstrapOptions ?? {};
199
+ if (configure) {
200
+ configure(new SwaggerBuilder(doc));
201
+ }
192
202
  this.app.use(
193
203
  path2,
194
204
  ...handlers,
195
205
  swaggerUi.serve,
196
206
  swaggerUi.setup(
197
- config,
198
- uiOptsWithDefaults,
207
+ doc,
208
+ { customSiteTitle: doc.info?.title, ...uiOpts },
199
209
  options,
200
210
  customCss,
201
211
  customfavIcon,
@@ -206,14 +216,11 @@ var ServerBuilder = class {
206
216
  return this;
207
217
  }
208
218
  };
209
- function buildExpressive(container) {
210
- const swaggerRef = {
211
- doc: {
212
- openapi: "3.1.0",
213
- info: {},
214
- paths: {},
215
- components: {}
216
- }
219
+ function buildExpressive(container, opts) {
220
+ const swaggerBootstrapOpts = opts?.swagger;
221
+ const swaggerRef = !swaggerBootstrapOpts || swaggerBootstrapOpts.enabled === false ? {} : {
222
+ doc: { openapi: "3.1.0", info: {}, paths: {}, components: {} },
223
+ bootstrapOptions: swaggerBootstrapOpts
217
224
  };
218
225
  return {
219
226
  expressiveServer(configs) {
@@ -226,42 +233,42 @@ function buildExpressive(container) {
226
233
  router,
227
234
  addRoute(context, ...handlers) {
228
235
  router[context.method](context.path, ...handlers);
229
- const {
230
- pathOverride,
231
- pathParameters,
232
- headerParameters,
233
- queryParameters,
234
- ...pathItemConfig
235
- } = context.oapi || {};
236
- const route = pathOverride ?? convertExpressPath(context.path);
237
- const pathItem = {
238
- // -- defaults --
239
- responses: {
240
- // has to be defined or else responses are not documented... ¯\_(ツ)_/¯
241
- "200": { description: "OK" },
242
- "201": { description: "Created" },
243
- "204": { description: "No Content" },
244
- "400": { description: "Bad Request" },
245
- "401": { description: "User Unauthorized" },
246
- "403": { description: "Forbidden" },
247
- "500": { description: "Internal Server Error" }
248
- },
249
- // -- group defaults --
250
- ...configs?.oapi || {},
251
- // -- overrides --
252
- ...pathItemConfig || {},
253
- parameters: [
254
- // ...(contract.pathParameters || []),
255
- ...headerParameters || [],
256
- ...queryParameters || []
257
- ]
258
- };
259
- if (pathParameters?.length) {
260
- pathItem.parameters.push(...pathParameters);
261
- } else {
262
- pathItem.parameters.push(...tryParsePathParameters(route));
263
- }
264
- if (swaggerRef.doc) {
236
+ if (swaggerRef?.doc) {
237
+ const {
238
+ pathOverride,
239
+ pathParameters,
240
+ headerParameters,
241
+ queryParameters,
242
+ ...pathItemConfig
243
+ } = context.oapi || {};
244
+ const route = pathOverride ?? convertExpressPath(context.path);
245
+ const pathItem = {
246
+ // -- defaults --
247
+ responses: {
248
+ // has to be defined or else responses are not documented... ¯\_(ツ)_/¯
249
+ "200": { description: "OK" },
250
+ "201": { description: "Created" },
251
+ "204": { description: "No Content" },
252
+ "400": { description: "Bad Request" },
253
+ "401": { description: "User Unauthorized" },
254
+ "403": { description: "Forbidden" },
255
+ "500": { description: "Internal Server Error" }
256
+ },
257
+ // -- group defaults --
258
+ ...configs?.oapi || {},
259
+ // -- overrides --
260
+ ...pathItemConfig || {},
261
+ parameters: [
262
+ // ...(contract.pathParameters || []),
263
+ ...headerParameters || [],
264
+ ...queryParameters || []
265
+ ]
266
+ };
267
+ if (pathParameters?.length) {
268
+ pathItem.parameters.push(...pathParameters);
269
+ } else {
270
+ pathItem.parameters.push(...tryParsePathParameters(route));
271
+ }
265
272
  if (!swaggerRef.doc.paths[route]) {
266
273
  swaggerRef.doc.paths[route] = {};
267
274
  }
@@ -503,9 +510,9 @@ var ApiResponse = class {
503
510
  };
504
511
 
505
512
  // src/index.ts
506
- function bootstrap(container) {
513
+ function bootstrap(container, opts) {
507
514
  return {
508
- ...buildExpressive(container),
515
+ ...buildExpressive(container, opts),
509
516
  ...buildMiddleware(container),
510
517
  silently: async (fn) => {
511
518
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@extk/expressive",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "type": "commonjs",
5
5
  "publishConfig": {
6
6
  "access": "public"