@tahminator/sapling 2.0.3 → 2.0.5-beta.2f539758
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 +94 -4
- package/dist/index.cjs +337 -137
- package/dist/index.d.cts +478 -13
- package/dist/index.d.mts +478 -13
- package/dist/index.mjs +322 -138
- package/package.json +4 -2
package/dist/index.mjs
CHANGED
|
@@ -240,7 +240,8 @@ var ParserError = class ParserError extends ResponseStatusError {
|
|
|
240
240
|
//#region src/helper/sapling.ts
|
|
241
241
|
const settings = {
|
|
242
242
|
serialize: JSON.stringify,
|
|
243
|
-
deserialize: JSON.parse
|
|
243
|
+
deserialize: JSON.parse,
|
|
244
|
+
openapi: { path: "/openapi.json" }
|
|
244
245
|
};
|
|
245
246
|
/**
|
|
246
247
|
* Collection of utility functions which are essential for Sapling to function.
|
|
@@ -345,7 +346,304 @@ var Sapling = class Sapling {
|
|
|
345
346
|
static setDeserializeFn(fn) {
|
|
346
347
|
settings.deserialize = fn;
|
|
347
348
|
}
|
|
349
|
+
static setOpenApiPath(path) {
|
|
350
|
+
settings.openapi.path = path;
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
//#endregion
|
|
354
|
+
//#region src/annotation/request.ts
|
|
355
|
+
const _requestSchemaStore = /* @__PURE__ */ new WeakMap();
|
|
356
|
+
/**
|
|
357
|
+
* Apply to a route method to have `request.body` be parsed by `schema`.
|
|
358
|
+
*
|
|
359
|
+
* This annotation will parse `request.body` & then override `request.body`.
|
|
360
|
+
* You can then just simply cast `request.body` for your use
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* ```ts
|
|
364
|
+
* const CREATE_BOOK_REQUEST_BODY_SCHEMA = z.object({
|
|
365
|
+
* name: z.string(),
|
|
366
|
+
* description: z.string().optional(),
|
|
367
|
+
* });
|
|
368
|
+
*
|
|
369
|
+
* ⠀@Controller({ prefix: "/api/book" })
|
|
370
|
+
* class BookController {
|
|
371
|
+
* ⠀@RequestBody(CREATE_BOOK_REQUEST_BODY_SCHEMA)
|
|
372
|
+
* ⠀@POST()
|
|
373
|
+
* public createBook(request: e.Request) {
|
|
374
|
+
* const { name, description } = request.body as unknown as z.infer<
|
|
375
|
+
* typeof CREATE_BOOK_REQUEST_BODY_SCHEMA
|
|
376
|
+
* >;
|
|
377
|
+
* }
|
|
378
|
+
* }
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
function RequestBody(schema) {
|
|
382
|
+
return (target, propertyKey) => {
|
|
383
|
+
const ctor = target.constructor;
|
|
384
|
+
const fnName = String(propertyKey);
|
|
385
|
+
_setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "body", schema, fnName);
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Apply to a route method to have `request.param` be parsed by `schema`.
|
|
390
|
+
*
|
|
391
|
+
* This annotation will parse `request.param` & then override `request.param`.
|
|
392
|
+
* You can then just simply cast `request.param` for your use
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* ```ts
|
|
396
|
+
* const GET_BOOK_REQUEST_PARAM_SCHEMA = z.object({
|
|
397
|
+
* bookId: z.string(),
|
|
398
|
+
* });
|
|
399
|
+
*
|
|
400
|
+
* ⠀@Controller({ prefix: "/api/book" })
|
|
401
|
+
* class BookController {
|
|
402
|
+
* ⠀@RequestParam(GET_BOOK_REQUEST_PARAM_SCHEMA)
|
|
403
|
+
* ⠀@GET("/:bookId")
|
|
404
|
+
* public getBook(request: e.Request) {
|
|
405
|
+
* const { bookId } = request.param as unknown as z.infer<
|
|
406
|
+
* typeof GET_BOOK_REQUEST_PARAM_SCHEMA
|
|
407
|
+
* >;
|
|
408
|
+
* }
|
|
409
|
+
* }
|
|
410
|
+
* ```
|
|
411
|
+
*/
|
|
412
|
+
function RequestParam(schema) {
|
|
413
|
+
return (target, propertyKey) => {
|
|
414
|
+
const ctor = target.constructor;
|
|
415
|
+
const fnName = String(propertyKey);
|
|
416
|
+
_setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "param", schema, fnName);
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Apply to a route method to have `request.query` be parsed by `schema`.
|
|
421
|
+
*
|
|
422
|
+
* This annotation will parse `request.query` & then override `request.query`.
|
|
423
|
+
* You can then just simply cast `request.query` for your use
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```ts
|
|
427
|
+
* const LIST_BOOKS_REQUEST_QUERY_SCHEMA = z.object({
|
|
428
|
+
* sort: z.enum(["name", "createdAt"]).optional(),
|
|
429
|
+
* q: z.string().optional(),
|
|
430
|
+
* });
|
|
431
|
+
*
|
|
432
|
+
* ⠀@Controller({ prefix: "/api/book" })
|
|
433
|
+
* class BookController {
|
|
434
|
+
* ⠀@RequestQuery(LIST_BOOKS_REQUEST_QUERY_SCHEMA)
|
|
435
|
+
* ⠀@GET()
|
|
436
|
+
* public listBooks(request: e.Request) {
|
|
437
|
+
* const { sort, q } = request.query as unknown as z.infer<
|
|
438
|
+
* typeof LIST_BOOKS_REQUEST_QUERY_SCHEMA
|
|
439
|
+
* >;
|
|
440
|
+
* }
|
|
441
|
+
* }
|
|
442
|
+
* ```
|
|
443
|
+
*/
|
|
444
|
+
function RequestQuery(schema) {
|
|
445
|
+
return (target, propertyKey) => {
|
|
446
|
+
const ctor = target.constructor;
|
|
447
|
+
const fnName = String(propertyKey);
|
|
448
|
+
_setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "query", schema, fnName);
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
function _getOrCreateRequestSchemaDefinition(ctor, fnName) {
|
|
452
|
+
const byFn = (() => {
|
|
453
|
+
const fn = _requestSchemaStore.get(ctor);
|
|
454
|
+
if (fn) return fn;
|
|
455
|
+
const newFn = /* @__PURE__ */ new Map();
|
|
456
|
+
_requestSchemaStore.set(ctor, newFn);
|
|
457
|
+
return newFn;
|
|
458
|
+
})();
|
|
459
|
+
const existing = byFn.get(fnName);
|
|
460
|
+
if (existing) return existing;
|
|
461
|
+
const created = {};
|
|
462
|
+
byFn.set(fnName, created);
|
|
463
|
+
return created;
|
|
464
|
+
}
|
|
465
|
+
function _setOnce(def, key, schema, fnName) {
|
|
466
|
+
if (def[key]) throw new Error(`Duplicate request schema for "${String(key)}" on method "${fnName}"`);
|
|
467
|
+
def[key] = schema;
|
|
468
|
+
}
|
|
469
|
+
function _getRequestSchemas(ctor, fnName) {
|
|
470
|
+
return _requestSchemaStore.get(ctor)?.get(fnName);
|
|
471
|
+
}
|
|
472
|
+
async function _parseOrThrow(schema, input, kind) {
|
|
473
|
+
const result = await schema["~standard"].validate(input);
|
|
474
|
+
if (result.issues) {
|
|
475
|
+
console.debug(`Failed to parse a schema`);
|
|
476
|
+
throw new ParserError(kind, result.issues, schema["~standard"].vendor);
|
|
477
|
+
}
|
|
478
|
+
return result.value;
|
|
479
|
+
}
|
|
480
|
+
//#endregion
|
|
481
|
+
//#region src/annotation/route.ts
|
|
482
|
+
const _routeStore = /* @__PURE__ */ new WeakMap();
|
|
483
|
+
/**
|
|
484
|
+
* Custom annotation that will store all routes inside of a map,
|
|
485
|
+
* which can then be used to initialize all the routes to the router.
|
|
486
|
+
*/
|
|
487
|
+
function _Route({ method, path = "" }) {
|
|
488
|
+
return (target, propertyKey) => {
|
|
489
|
+
const ctor = target.constructor;
|
|
490
|
+
const list = _routeStore.get(ctor) ?? [];
|
|
491
|
+
list.push({
|
|
492
|
+
method,
|
|
493
|
+
path: path ?? "",
|
|
494
|
+
fnName: String(propertyKey)
|
|
495
|
+
});
|
|
496
|
+
_routeStore.set(ctor, list);
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Register GET route on the given path (default "") for the given controller.
|
|
501
|
+
*/
|
|
502
|
+
const GET = (path = "") => _Route({
|
|
503
|
+
method: "GET",
|
|
504
|
+
path
|
|
505
|
+
});
|
|
506
|
+
/**
|
|
507
|
+
* Register POST route on the given path (default "") for the given controller.
|
|
508
|
+
*/
|
|
509
|
+
const POST = (path = "") => _Route({
|
|
510
|
+
method: "POST",
|
|
511
|
+
path
|
|
512
|
+
});
|
|
513
|
+
/**
|
|
514
|
+
* Register PUT route on the given path (default "") for the given controller.
|
|
515
|
+
*/
|
|
516
|
+
const PUT = (path = "") => _Route({
|
|
517
|
+
method: "PUT",
|
|
518
|
+
path
|
|
519
|
+
});
|
|
520
|
+
/**
|
|
521
|
+
* Register DELETE route on the given path (default "") for the given controller.
|
|
522
|
+
*/
|
|
523
|
+
const DELETE = (path = "") => _Route({
|
|
524
|
+
method: "DELETE",
|
|
525
|
+
path
|
|
526
|
+
});
|
|
527
|
+
/**
|
|
528
|
+
* Register OPTIONS route on the given path (default "") for the given controller.
|
|
529
|
+
*/
|
|
530
|
+
const OPTIONS = (path = "") => _Route({
|
|
531
|
+
method: "OPTIONS",
|
|
532
|
+
path
|
|
533
|
+
});
|
|
534
|
+
/**
|
|
535
|
+
* Register PATCH route on the given path (default "") for the given controller.
|
|
536
|
+
*/
|
|
537
|
+
const PATCH = (path = "") => _Route({
|
|
538
|
+
method: "PATCH",
|
|
539
|
+
path
|
|
540
|
+
});
|
|
541
|
+
/**
|
|
542
|
+
* Register HEAD route on the given path (default "") for the given controller.
|
|
543
|
+
*/
|
|
544
|
+
const HEAD = (path = "") => _Route({
|
|
545
|
+
method: "HEAD",
|
|
546
|
+
path
|
|
547
|
+
});
|
|
548
|
+
/**
|
|
549
|
+
* Register a middleware route on the given path (default "") for the given controller.
|
|
550
|
+
*/
|
|
551
|
+
const Middleware = (path = "") => _Route({
|
|
552
|
+
method: "USE",
|
|
553
|
+
path
|
|
554
|
+
});
|
|
555
|
+
/**
|
|
556
|
+
* Given a class constructor, fetch all the routes attached.
|
|
557
|
+
*/
|
|
558
|
+
function _getRoutes(ctor) {
|
|
559
|
+
return _routeStore.get(ctor) ?? [];
|
|
560
|
+
}
|
|
561
|
+
//#endregion
|
|
562
|
+
//#region src/helper/openapi.ts
|
|
563
|
+
var OpenAPIGenerator = class {
|
|
564
|
+
constructor() {
|
|
565
|
+
this.controllers = /* @__PURE__ */ new Set();
|
|
566
|
+
this.config = {
|
|
567
|
+
title: "API",
|
|
568
|
+
version: "1.0.0"
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
setConfig(config) {
|
|
572
|
+
this.config = config;
|
|
573
|
+
}
|
|
574
|
+
registerController(controllerClass, prefix) {
|
|
575
|
+
this.controllers.add({
|
|
576
|
+
class: controllerClass,
|
|
577
|
+
prefix
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
generateSpec() {
|
|
581
|
+
const config = this.config;
|
|
582
|
+
const paths = {};
|
|
583
|
+
for (const { class: controllerClass, prefix } of this.controllers) {
|
|
584
|
+
const routes = _getRoutes(controllerClass);
|
|
585
|
+
for (const route of routes) {
|
|
586
|
+
if (route.method === "USE") continue;
|
|
587
|
+
const schemas = _getRequestSchemas(controllerClass, route.fnName);
|
|
588
|
+
const fullPath = route.path instanceof RegExp ? route.path.source : prefix + route.path;
|
|
589
|
+
const openApiPath = typeof fullPath === "string" ? fullPath.replace(/:(\w+)/g, "{$1}") : fullPath;
|
|
590
|
+
if (!paths[openApiPath]) paths[openApiPath] = {};
|
|
591
|
+
const operation = { responses: { "200": { description: "Successful response" } } };
|
|
592
|
+
const parameters = [];
|
|
593
|
+
if (schemas?.param) {
|
|
594
|
+
const paramSchema = this.toJsonSchema(schemas.param);
|
|
595
|
+
if (paramSchema.type === "object" && paramSchema.properties) for (const [name, schema] of Object.entries(paramSchema.properties)) parameters.push({
|
|
596
|
+
name,
|
|
597
|
+
in: "path",
|
|
598
|
+
required: true,
|
|
599
|
+
schema
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
if (schemas?.query) {
|
|
603
|
+
const querySchema = this.toJsonSchema(schemas.query);
|
|
604
|
+
if (querySchema.type === "object" && querySchema.properties) for (const [name, schema] of Object.entries(querySchema.properties)) {
|
|
605
|
+
const isRequired = Array.isArray(querySchema.required) && querySchema.required.includes(name);
|
|
606
|
+
parameters.push({
|
|
607
|
+
name,
|
|
608
|
+
in: "query",
|
|
609
|
+
required: isRequired,
|
|
610
|
+
schema
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
if (parameters.length > 0) operation.parameters = parameters;
|
|
615
|
+
if (schemas?.body) operation.requestBody = {
|
|
616
|
+
required: true,
|
|
617
|
+
content: { "application/json": { schema: this.toJsonSchema(schemas.body) } }
|
|
618
|
+
};
|
|
619
|
+
const method = route.method.toLowerCase();
|
|
620
|
+
paths[openApiPath][method] = operation;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return {
|
|
624
|
+
openapi: "3.0.0",
|
|
625
|
+
info: {
|
|
626
|
+
title: config.title,
|
|
627
|
+
version: config.version,
|
|
628
|
+
description: config.description
|
|
629
|
+
},
|
|
630
|
+
paths
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
toJsonSchema(schema) {
|
|
634
|
+
return schema["~standard"].jsonSchema.output({ target: "openapi-3.0" });
|
|
635
|
+
}
|
|
348
636
|
};
|
|
637
|
+
const openApiGenerator = new OpenAPIGenerator();
|
|
638
|
+
function _registerControllerClass(controllerClass, prefix) {
|
|
639
|
+
openApiGenerator.registerController(controllerClass, prefix);
|
|
640
|
+
}
|
|
641
|
+
function setOpenApiConfig(config) {
|
|
642
|
+
openApiGenerator.setConfig(config);
|
|
643
|
+
}
|
|
644
|
+
function generateOpenApiSpec() {
|
|
645
|
+
return openApiGenerator.generateSpec();
|
|
646
|
+
}
|
|
349
647
|
//#endregion
|
|
350
648
|
//#region src/types.ts
|
|
351
649
|
const methodResolve = {
|
|
@@ -479,140 +777,6 @@ function _resolve(ctor) {
|
|
|
479
777
|
return _InjectableRegistry.get(ctor);
|
|
480
778
|
}
|
|
481
779
|
//#endregion
|
|
482
|
-
//#region src/annotation/request.ts
|
|
483
|
-
const _requestSchemaStore = /* @__PURE__ */ new WeakMap();
|
|
484
|
-
function _getOrCreateRequestSchemaDefinition(ctor, fnName) {
|
|
485
|
-
const byFn = (() => {
|
|
486
|
-
const fn = _requestSchemaStore.get(ctor);
|
|
487
|
-
if (fn) return fn;
|
|
488
|
-
const newFn = /* @__PURE__ */ new Map();
|
|
489
|
-
_requestSchemaStore.set(ctor, newFn);
|
|
490
|
-
return newFn;
|
|
491
|
-
})();
|
|
492
|
-
const existing = byFn.get(fnName);
|
|
493
|
-
if (existing) return existing;
|
|
494
|
-
const created = {};
|
|
495
|
-
byFn.set(fnName, created);
|
|
496
|
-
return created;
|
|
497
|
-
}
|
|
498
|
-
function _setOnce(def, key, schema, fnName) {
|
|
499
|
-
if (def[key]) throw new Error(`Duplicate request schema for "${String(key)}" on method "${fnName}"`);
|
|
500
|
-
def[key] = schema;
|
|
501
|
-
}
|
|
502
|
-
function RequestBody(schema) {
|
|
503
|
-
return (target, propertyKey) => {
|
|
504
|
-
const ctor = target.constructor;
|
|
505
|
-
const fnName = String(propertyKey);
|
|
506
|
-
_setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "body", schema, fnName);
|
|
507
|
-
};
|
|
508
|
-
}
|
|
509
|
-
function RequestParam(schema) {
|
|
510
|
-
return (target, propertyKey) => {
|
|
511
|
-
const ctor = target.constructor;
|
|
512
|
-
const fnName = String(propertyKey);
|
|
513
|
-
_setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "param", schema, fnName);
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
|
-
function RequestQuery(schema) {
|
|
517
|
-
return (target, propertyKey) => {
|
|
518
|
-
const ctor = target.constructor;
|
|
519
|
-
const fnName = String(propertyKey);
|
|
520
|
-
_setOnce(_getOrCreateRequestSchemaDefinition(ctor, fnName), "query", schema, fnName);
|
|
521
|
-
};
|
|
522
|
-
}
|
|
523
|
-
function _getRequestSchemas(ctor, fnName) {
|
|
524
|
-
return _requestSchemaStore.get(ctor)?.get(fnName);
|
|
525
|
-
}
|
|
526
|
-
async function _parseOrThrow(schema, input, kind) {
|
|
527
|
-
const result = await schema["~standard"].validate(input);
|
|
528
|
-
if (result.issues) {
|
|
529
|
-
console.debug(`Failed to parse a schema`);
|
|
530
|
-
throw new ParserError(kind, result.issues, schema["~standard"].vendor);
|
|
531
|
-
}
|
|
532
|
-
return result.value;
|
|
533
|
-
}
|
|
534
|
-
//#endregion
|
|
535
|
-
//#region src/annotation/route.ts
|
|
536
|
-
const _routeStore = /* @__PURE__ */ new WeakMap();
|
|
537
|
-
/**
|
|
538
|
-
* Custom annotation that will store all routes inside of a map,
|
|
539
|
-
* which can then be used to initialize all the routes to the router.
|
|
540
|
-
*/
|
|
541
|
-
function _Route({ method, path = "" }) {
|
|
542
|
-
return (target, propertyKey) => {
|
|
543
|
-
const ctor = target.constructor;
|
|
544
|
-
const list = _routeStore.get(ctor) ?? [];
|
|
545
|
-
list.push({
|
|
546
|
-
method,
|
|
547
|
-
path: path ?? "",
|
|
548
|
-
fnName: String(propertyKey)
|
|
549
|
-
});
|
|
550
|
-
_routeStore.set(ctor, list);
|
|
551
|
-
};
|
|
552
|
-
}
|
|
553
|
-
/**
|
|
554
|
-
* Register GET route on the given path (default "") for the given controller.
|
|
555
|
-
*/
|
|
556
|
-
const GET = (path = "") => _Route({
|
|
557
|
-
method: "GET",
|
|
558
|
-
path
|
|
559
|
-
});
|
|
560
|
-
/**
|
|
561
|
-
* Register POST route on the given path (default "") for the given controller.
|
|
562
|
-
*/
|
|
563
|
-
const POST = (path = "") => _Route({
|
|
564
|
-
method: "POST",
|
|
565
|
-
path
|
|
566
|
-
});
|
|
567
|
-
/**
|
|
568
|
-
* Register PUT route on the given path (default "") for the given controller.
|
|
569
|
-
*/
|
|
570
|
-
const PUT = (path = "") => _Route({
|
|
571
|
-
method: "PUT",
|
|
572
|
-
path
|
|
573
|
-
});
|
|
574
|
-
/**
|
|
575
|
-
* Register DELETE route on the given path (default "") for the given controller.
|
|
576
|
-
*/
|
|
577
|
-
const DELETE = (path = "") => _Route({
|
|
578
|
-
method: "DELETE",
|
|
579
|
-
path
|
|
580
|
-
});
|
|
581
|
-
/**
|
|
582
|
-
* Register OPTIONS route on the given path (default "") for the given controller.
|
|
583
|
-
*/
|
|
584
|
-
const OPTIONS = (path = "") => _Route({
|
|
585
|
-
method: "OPTIONS",
|
|
586
|
-
path
|
|
587
|
-
});
|
|
588
|
-
/**
|
|
589
|
-
* Register PATCH route on the given path (default "") for the given controller.
|
|
590
|
-
*/
|
|
591
|
-
const PATCH = (path = "") => _Route({
|
|
592
|
-
method: "PATCH",
|
|
593
|
-
path
|
|
594
|
-
});
|
|
595
|
-
/**
|
|
596
|
-
* Register HEAD route on the given path (default "") for the given controller.
|
|
597
|
-
*/
|
|
598
|
-
const HEAD = (path = "") => _Route({
|
|
599
|
-
method: "HEAD",
|
|
600
|
-
path
|
|
601
|
-
});
|
|
602
|
-
/**
|
|
603
|
-
* Register a middleware route on the given path (default "") for the given controller.
|
|
604
|
-
*/
|
|
605
|
-
const Middleware = (path = "") => _Route({
|
|
606
|
-
method: "USE",
|
|
607
|
-
path
|
|
608
|
-
});
|
|
609
|
-
/**
|
|
610
|
-
* Given a class constructor, fetch all the routes attached.
|
|
611
|
-
*/
|
|
612
|
-
function _getRoutes(ctor) {
|
|
613
|
-
return _routeStore.get(ctor) ?? [];
|
|
614
|
-
}
|
|
615
|
-
//#endregion
|
|
616
780
|
//#region src/annotation/controller.ts
|
|
617
781
|
const _ControllerRegistry = /* @__PURE__ */ new WeakMap();
|
|
618
782
|
/**
|
|
@@ -624,6 +788,7 @@ const _ControllerRegistry = /* @__PURE__ */ new WeakMap();
|
|
|
624
788
|
function Controller({ prefix = "", deps = [] } = {}) {
|
|
625
789
|
return (target) => {
|
|
626
790
|
const targetClass = target;
|
|
791
|
+
_registerControllerClass(target, prefix);
|
|
627
792
|
const router = Router();
|
|
628
793
|
const routes = _getRoutes(target);
|
|
629
794
|
const usedRoutes = /* @__PURE__ */ new Set();
|
|
@@ -715,7 +880,7 @@ function __decorate(decorators, target, key, desc) {
|
|
|
715
880
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
716
881
|
}
|
|
717
882
|
//#endregion
|
|
718
|
-
//#region src/middleware/default/base.ts
|
|
883
|
+
//#region src/middleware/default/error/base.ts
|
|
719
884
|
let DefaultBaseErrorMiddleware = class DefaultBaseErrorMiddleware {
|
|
720
885
|
handle(err, _request, _response, _next) {
|
|
721
886
|
console.error("[Error]", err);
|
|
@@ -725,7 +890,17 @@ let DefaultBaseErrorMiddleware = class DefaultBaseErrorMiddleware {
|
|
|
725
890
|
__decorate([Middleware()], DefaultBaseErrorMiddleware.prototype, "handle", null);
|
|
726
891
|
DefaultBaseErrorMiddleware = __decorate([MiddlewareClass()], DefaultBaseErrorMiddleware);
|
|
727
892
|
//#endregion
|
|
728
|
-
//#region src/middleware/default/
|
|
893
|
+
//#region src/middleware/default/error/parse.ts
|
|
894
|
+
let DefaultParserErrorMiddleware = class DefaultParserErrorMiddleware {
|
|
895
|
+
handle(err, _request, _response, next) {
|
|
896
|
+
if (err instanceof ParserError) return ResponseEntity.status(err.status).body({ message: err.message });
|
|
897
|
+
next(err);
|
|
898
|
+
}
|
|
899
|
+
};
|
|
900
|
+
__decorate([Middleware()], DefaultParserErrorMiddleware.prototype, "handle", null);
|
|
901
|
+
DefaultParserErrorMiddleware = __decorate([MiddlewareClass()], DefaultParserErrorMiddleware);
|
|
902
|
+
//#endregion
|
|
903
|
+
//#region src/middleware/default/error/responsestatus.ts
|
|
729
904
|
let DefaultResponseStatusErrorMiddleware = class DefaultResponseStatusErrorMiddleware {
|
|
730
905
|
handle(err, _request, _response, next) {
|
|
731
906
|
if (err instanceof ResponseStatusError) return ResponseEntity.status(err.status).body({ message: err.message });
|
|
@@ -735,4 +910,13 @@ let DefaultResponseStatusErrorMiddleware = class DefaultResponseStatusErrorMiddl
|
|
|
735
910
|
__decorate([Middleware()], DefaultResponseStatusErrorMiddleware.prototype, "handle", null);
|
|
736
911
|
DefaultResponseStatusErrorMiddleware = __decorate([MiddlewareClass()], DefaultResponseStatusErrorMiddleware);
|
|
737
912
|
//#endregion
|
|
738
|
-
|
|
913
|
+
//#region src/middleware/default/openapi/index.ts
|
|
914
|
+
let DefaultOpenApiMiddleware = class DefaultOpenApiMiddleware {
|
|
915
|
+
handle(_request, _response, _next) {
|
|
916
|
+
return ResponseEntity.ok().body(generateOpenApiSpec());
|
|
917
|
+
}
|
|
918
|
+
};
|
|
919
|
+
__decorate([GET("/openapi.json")], DefaultOpenApiMiddleware.prototype, "handle", null);
|
|
920
|
+
DefaultOpenApiMiddleware = __decorate([MiddlewareClass()], DefaultOpenApiMiddleware);
|
|
921
|
+
//#endregion
|
|
922
|
+
export { Controller, DELETE, DefaultBaseErrorMiddleware, DefaultOpenApiMiddleware, DefaultParserErrorMiddleware, DefaultResponseStatusErrorMiddleware, GET, HEAD, Html404ErrorPage, HttpStatus, Injectable, Middleware, MiddlewareClass, OPTIONS, PATCH, POST, PUT, ParserError, RedirectView, RequestBody, RequestParam, RequestQuery, ResponseEntity, ResponseEntityBuilder, ResponseStatusError, Sapling, _ControllerRegistry, _InjectableDeps, _InjectableRegistry, _Route, _getRequestSchemas, _getRoutes, _parseOrThrow, _registerControllerClass, _resolve, generateOpenApiSpec, methodResolve, openApiGenerator, setOpenApiConfig };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tahminator/sapling",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5-beta.2f539758",
|
|
4
4
|
"author": "Tahmid Ahmed",
|
|
5
5
|
"description": "A library to help you write cleaner Express.js code",
|
|
6
6
|
"repository": {
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"@types/express": "^5",
|
|
46
46
|
"@types/supertest": "^7.2.0",
|
|
47
47
|
"@vitest/coverage-istanbul": "^4.1.2",
|
|
48
|
+
"openapi-types": "12.1.3",
|
|
48
49
|
"eslint": "^10.1.0",
|
|
49
50
|
"eslint-plugin-perfectionist": "^5.7.0",
|
|
50
51
|
"globals": "^17.4.0",
|
|
@@ -60,6 +61,7 @@
|
|
|
60
61
|
"zod": "^4.4.3"
|
|
61
62
|
},
|
|
62
63
|
"inlinedDependencies": {
|
|
63
|
-
"@standard-schema/spec": "1.1.0"
|
|
64
|
+
"@standard-schema/spec": "1.1.0",
|
|
65
|
+
"openapi-types": "12.1.3"
|
|
64
66
|
}
|
|
65
67
|
}
|