@tahminator/sapling 2.0.4 → 2.0.5-beta.23c37926
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 +305 -138
- package/dist/index.d.cts +429 -13
- package/dist/index.d.mts +429 -13
- package/dist/index.mjs +287 -139
- package/package.json +8 -2
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import e, { Router } from "express";
|
|
2
|
+
import swagger from "swagger-ui-express";
|
|
2
3
|
//#region src/html/404.ts
|
|
3
4
|
/**
|
|
4
5
|
* Default Express.js 404 error page, as a string.
|
|
@@ -238,9 +239,13 @@ var ParserError = class ParserError extends ResponseStatusError {
|
|
|
238
239
|
};
|
|
239
240
|
//#endregion
|
|
240
241
|
//#region src/helper/sapling.ts
|
|
241
|
-
const
|
|
242
|
+
const _settings = {
|
|
242
243
|
serialize: JSON.stringify,
|
|
243
|
-
deserialize: JSON.parse
|
|
244
|
+
deserialize: JSON.parse,
|
|
245
|
+
doc: {
|
|
246
|
+
openApiPath: "/openapi.json",
|
|
247
|
+
swaggerPath: "/swagger.html"
|
|
248
|
+
}
|
|
244
249
|
};
|
|
245
250
|
/**
|
|
246
251
|
* Collection of utility functions which are essential for Sapling to function.
|
|
@@ -319,13 +324,13 @@ var Sapling = class Sapling {
|
|
|
319
324
|
* @defaultValue `JSON.stringify`
|
|
320
325
|
*/
|
|
321
326
|
static serialize(value) {
|
|
322
|
-
return
|
|
327
|
+
return _settings.serialize(value);
|
|
323
328
|
}
|
|
324
329
|
/**
|
|
325
330
|
* Replace the function used for `serialize`.
|
|
326
331
|
*/
|
|
327
332
|
static setSerializeFn(fn) {
|
|
328
|
-
|
|
333
|
+
_settings.serialize = fn;
|
|
329
334
|
}
|
|
330
335
|
/**
|
|
331
336
|
* De-serialize a JSON string back to a JavaScript object.
|
|
@@ -337,148 +342,22 @@ var Sapling = class Sapling {
|
|
|
337
342
|
* @defaultValue `JSON.parse`
|
|
338
343
|
*/
|
|
339
344
|
static deserialize(value) {
|
|
340
|
-
return
|
|
345
|
+
return _settings.deserialize(value);
|
|
341
346
|
}
|
|
342
347
|
/**
|
|
343
348
|
* Replace the function used for `deserialize`
|
|
344
349
|
*/
|
|
345
350
|
static setDeserializeFn(fn) {
|
|
346
|
-
|
|
351
|
+
_settings.deserialize = fn;
|
|
347
352
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
//#region src/types.ts
|
|
351
|
-
const methodResolve = {
|
|
352
|
-
GET: "get",
|
|
353
|
-
PUT: "put",
|
|
354
|
-
POST: "post",
|
|
355
|
-
DELETE: "delete",
|
|
356
|
-
OPTIONS: "options",
|
|
357
|
-
PATCH: "patch",
|
|
358
|
-
HEAD: "head",
|
|
359
|
-
USE: "use"
|
|
360
|
-
};
|
|
361
|
-
//#endregion
|
|
362
|
-
//#region lib/weakmap.ts
|
|
363
|
-
/**
|
|
364
|
-
* WeakMap that is iterable.
|
|
365
|
-
*/
|
|
366
|
-
var IterableWeakMap = class IterableWeakMap {
|
|
367
|
-
#weakMap = /* @__PURE__ */ new WeakMap();
|
|
368
|
-
#refSet = /* @__PURE__ */ new Set();
|
|
369
|
-
#finalizationGroup = new FinalizationRegistry(IterableWeakMap.#cleanup);
|
|
370
|
-
static #cleanup(heldValue) {
|
|
371
|
-
heldValue.set.delete(heldValue.ref);
|
|
353
|
+
static setOpenApiPath(path) {
|
|
354
|
+
_settings.doc.openApiPath = path;
|
|
372
355
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
set(key, value) {
|
|
377
|
-
const ref = new WeakRef(key);
|
|
378
|
-
this.#weakMap.set(key, {
|
|
379
|
-
value,
|
|
380
|
-
ref
|
|
381
|
-
});
|
|
382
|
-
this.#refSet.add(ref);
|
|
383
|
-
this.#finalizationGroup.register(key, {
|
|
384
|
-
set: this.#refSet,
|
|
385
|
-
ref
|
|
386
|
-
}, ref);
|
|
387
|
-
return this;
|
|
388
|
-
}
|
|
389
|
-
get(key) {
|
|
390
|
-
return this.#weakMap.get(key)?.value;
|
|
391
|
-
}
|
|
392
|
-
delete(key) {
|
|
393
|
-
const entry = this.#weakMap.get(key);
|
|
394
|
-
if (!entry) return false;
|
|
395
|
-
this.#weakMap.delete(key);
|
|
396
|
-
this.#refSet.delete(entry.ref);
|
|
397
|
-
this.#finalizationGroup.unregister(entry.ref);
|
|
398
|
-
return true;
|
|
399
|
-
}
|
|
400
|
-
*[Symbol.iterator]() {
|
|
401
|
-
for (const ref of this.#refSet) {
|
|
402
|
-
const key = ref.deref();
|
|
403
|
-
if (!key) continue;
|
|
404
|
-
const entry = this.#weakMap.get(key);
|
|
405
|
-
if (entry) yield [key, entry.value];
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
entries() {
|
|
409
|
-
return this[Symbol.iterator]();
|
|
410
|
-
}
|
|
411
|
-
*keys() {
|
|
412
|
-
for (const [key] of this) yield key;
|
|
413
|
-
}
|
|
414
|
-
*values() {
|
|
415
|
-
for (const [, value] of this) yield value;
|
|
416
|
-
}
|
|
417
|
-
forEach(callback, thisArg) {
|
|
418
|
-
for (const [key, value] of this) callback.call(thisArg, value, key, this);
|
|
356
|
+
static setSwaggerPath(path) {
|
|
357
|
+
_settings.doc.swaggerPath = path;
|
|
419
358
|
}
|
|
420
359
|
};
|
|
421
360
|
//#endregion
|
|
422
|
-
//#region src/annotation/injectable.ts
|
|
423
|
-
const _InjectableRegistry = /* @__PURE__ */ new WeakMap();
|
|
424
|
-
const _InjectableDeps = new IterableWeakMap();
|
|
425
|
-
/**
|
|
426
|
-
* Mark the class as an injectable to be handled by Sapling. The class can now be
|
|
427
|
-
* be injected into other classes, as well as allow the class to inject other `@Injectable` classes.
|
|
428
|
-
*
|
|
429
|
-
* @argument deps - An optional array to define any dependencies that this class may require.
|
|
430
|
-
*/
|
|
431
|
-
function Injectable(deps = []) {
|
|
432
|
-
return function(target) {
|
|
433
|
-
_InjectableRegistry.set(target, null);
|
|
434
|
-
_InjectableDeps.set(target, deps);
|
|
435
|
-
};
|
|
436
|
-
}
|
|
437
|
-
/**
|
|
438
|
-
* Resolves and instantiates a class along with all of it's transitive dependencies.
|
|
439
|
-
*
|
|
440
|
-
* Uses topological sort (Kahn's algorithm) to ensure that the dependency graph is created
|
|
441
|
-
* in a correct order.
|
|
442
|
-
*
|
|
443
|
-
* When `resolve` is first called (usually during controller registration),
|
|
444
|
-
* it will compute the dependency graph of all `@Injectable` classes and instantiates
|
|
445
|
-
* them in the correct order.
|
|
446
|
-
*
|
|
447
|
-
* Subsequent calls to dependencies that have already been resolved are cached, so they will
|
|
448
|
-
* re-use the created singletons instead of re-instantiation.
|
|
449
|
-
*/
|
|
450
|
-
function _resolve(ctor) {
|
|
451
|
-
const inDegree = /* @__PURE__ */ new Map();
|
|
452
|
-
const graph = /* @__PURE__ */ new Map();
|
|
453
|
-
_InjectableDeps.forEach((deps, node) => {
|
|
454
|
-
inDegree.set(node, inDegree.get(node) || 0);
|
|
455
|
-
deps.forEach((dep) => {
|
|
456
|
-
if (dep === void 0) throw new Error(`There is an @Injectable (${node.name}) which has a dependency that cannot be found. This is likely caused by a circular dependency.`);
|
|
457
|
-
inDegree.set(dep, inDegree.get(dep) || 0);
|
|
458
|
-
inDegree.set(node, inDegree.get(node) + 1);
|
|
459
|
-
if (!graph.has(dep)) graph.set(dep, []);
|
|
460
|
-
graph.get(dep).push(node);
|
|
461
|
-
});
|
|
462
|
-
});
|
|
463
|
-
const queue = [];
|
|
464
|
-
inDegree.forEach((deg, node) => {
|
|
465
|
-
if (deg === 0) queue.push(node);
|
|
466
|
-
});
|
|
467
|
-
while (queue.length) {
|
|
468
|
-
const current = queue.shift();
|
|
469
|
-
if (!_InjectableRegistry.get(current)) {
|
|
470
|
-
const instance = new current(...(_InjectableDeps.get(current) || []).map((dep) => _InjectableRegistry.get(dep)));
|
|
471
|
-
_InjectableRegistry.set(current, instance);
|
|
472
|
-
}
|
|
473
|
-
(graph.get(current) || []).forEach((neighbor) => {
|
|
474
|
-
inDegree.set(neighbor, (inDegree.get(neighbor) ?? 0) - 1);
|
|
475
|
-
if (inDegree.get(neighbor) === 0) queue.push(neighbor);
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
|
-
if (!_InjectableRegistry.get(ctor)) throw new Error("Circular dependency detected or injectable not registered");
|
|
479
|
-
return _InjectableRegistry.get(ctor);
|
|
480
|
-
}
|
|
481
|
-
//#endregion
|
|
482
361
|
//#region src/annotation/request.ts
|
|
483
362
|
const _requestSchemaStore = /* @__PURE__ */ new WeakMap();
|
|
484
363
|
/**
|
|
@@ -687,6 +566,229 @@ function _getRoutes(ctor) {
|
|
|
687
566
|
return _routeStore.get(ctor) ?? [];
|
|
688
567
|
}
|
|
689
568
|
//#endregion
|
|
569
|
+
//#region src/helper/openapi.ts
|
|
570
|
+
var OpenAPIGenerator = class {
|
|
571
|
+
constructor() {
|
|
572
|
+
this.controllers = /* @__PURE__ */ new Set();
|
|
573
|
+
this.config = {
|
|
574
|
+
title: "API",
|
|
575
|
+
version: "1.0.0"
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
setConfig(config) {
|
|
579
|
+
this.config = config;
|
|
580
|
+
}
|
|
581
|
+
registerController(controllerClass, prefix) {
|
|
582
|
+
this.controllers.add({
|
|
583
|
+
class: controllerClass,
|
|
584
|
+
prefix
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
generateSpec() {
|
|
588
|
+
const config = this.config;
|
|
589
|
+
const paths = {};
|
|
590
|
+
for (const { class: controllerClass, prefix } of this.controllers) {
|
|
591
|
+
const routes = _getRoutes(controllerClass);
|
|
592
|
+
for (const route of routes) {
|
|
593
|
+
if (route.method === "USE") continue;
|
|
594
|
+
const schemas = _getRequestSchemas(controllerClass, route.fnName);
|
|
595
|
+
const fullPath = route.path instanceof RegExp ? route.path.source : prefix + route.path;
|
|
596
|
+
const openApiPath = typeof fullPath === "string" ? fullPath.replace(/:(\w+)/g, "{$1}") : fullPath;
|
|
597
|
+
if (!paths[openApiPath]) paths[openApiPath] = {};
|
|
598
|
+
const operation = { responses: { "200": { description: "Successful response" } } };
|
|
599
|
+
const parameters = [];
|
|
600
|
+
if (schemas?.param) {
|
|
601
|
+
const paramSchema = this.toJsonSchema(schemas.param);
|
|
602
|
+
if (paramSchema.type === "object" && paramSchema.properties) for (const [name, schema] of Object.entries(paramSchema.properties)) parameters.push({
|
|
603
|
+
name,
|
|
604
|
+
in: "path",
|
|
605
|
+
required: true,
|
|
606
|
+
schema
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
if (schemas?.query) {
|
|
610
|
+
const querySchema = this.toJsonSchema(schemas.query);
|
|
611
|
+
if (querySchema.type === "object" && querySchema.properties) for (const [name, schema] of Object.entries(querySchema.properties)) {
|
|
612
|
+
const isRequired = Array.isArray(querySchema.required) && querySchema.required.includes(name);
|
|
613
|
+
parameters.push({
|
|
614
|
+
name,
|
|
615
|
+
in: "query",
|
|
616
|
+
required: isRequired,
|
|
617
|
+
schema
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
if (parameters.length > 0) operation.parameters = parameters;
|
|
622
|
+
if (schemas?.body) operation.requestBody = {
|
|
623
|
+
required: true,
|
|
624
|
+
content: { "application/json": { schema: this.toJsonSchema(schemas.body) } }
|
|
625
|
+
};
|
|
626
|
+
const method = route.method.toLowerCase();
|
|
627
|
+
paths[openApiPath][method] = operation;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
return {
|
|
631
|
+
openapi: "3.0.0",
|
|
632
|
+
info: {
|
|
633
|
+
title: config.title,
|
|
634
|
+
version: config.version,
|
|
635
|
+
description: config.description
|
|
636
|
+
},
|
|
637
|
+
paths
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
toJsonSchema(schema) {
|
|
641
|
+
try {
|
|
642
|
+
return schema["~standard"].jsonSchema.output({ target: "openapi-3.0" });
|
|
643
|
+
} catch (e) {
|
|
644
|
+
if (e instanceof Error && e.message.includes("Transforms cannot be represented in JSON Schema")) throw new Error(`${e.message}.\nIt appears that you are using z.transform() - it is highly recommended that you use z.codec instead - https://zod.dev/codecs`);
|
|
645
|
+
throw e;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
const openApiGenerator = new OpenAPIGenerator();
|
|
650
|
+
function _registerControllerClass(controllerClass, prefix) {
|
|
651
|
+
openApiGenerator.registerController(controllerClass, prefix);
|
|
652
|
+
}
|
|
653
|
+
function _setOpenApiConfig(config) {
|
|
654
|
+
openApiGenerator.setConfig(config);
|
|
655
|
+
}
|
|
656
|
+
function _generateOpenApiSpec() {
|
|
657
|
+
return openApiGenerator.generateSpec();
|
|
658
|
+
}
|
|
659
|
+
//#endregion
|
|
660
|
+
//#region src/types.ts
|
|
661
|
+
const methodResolve = {
|
|
662
|
+
GET: "get",
|
|
663
|
+
PUT: "put",
|
|
664
|
+
POST: "post",
|
|
665
|
+
DELETE: "delete",
|
|
666
|
+
OPTIONS: "options",
|
|
667
|
+
PATCH: "patch",
|
|
668
|
+
HEAD: "head",
|
|
669
|
+
USE: "use"
|
|
670
|
+
};
|
|
671
|
+
//#endregion
|
|
672
|
+
//#region lib/weakmap.ts
|
|
673
|
+
/**
|
|
674
|
+
* WeakMap that is iterable.
|
|
675
|
+
*/
|
|
676
|
+
var IterableWeakMap = class IterableWeakMap {
|
|
677
|
+
#weakMap = /* @__PURE__ */ new WeakMap();
|
|
678
|
+
#refSet = /* @__PURE__ */ new Set();
|
|
679
|
+
#finalizationGroup = new FinalizationRegistry(IterableWeakMap.#cleanup);
|
|
680
|
+
static #cleanup(heldValue) {
|
|
681
|
+
heldValue.set.delete(heldValue.ref);
|
|
682
|
+
}
|
|
683
|
+
constructor(iterable) {
|
|
684
|
+
if (iterable) for (const [key, value] of iterable) this.set(key, value);
|
|
685
|
+
}
|
|
686
|
+
set(key, value) {
|
|
687
|
+
const ref = new WeakRef(key);
|
|
688
|
+
this.#weakMap.set(key, {
|
|
689
|
+
value,
|
|
690
|
+
ref
|
|
691
|
+
});
|
|
692
|
+
this.#refSet.add(ref);
|
|
693
|
+
this.#finalizationGroup.register(key, {
|
|
694
|
+
set: this.#refSet,
|
|
695
|
+
ref
|
|
696
|
+
}, ref);
|
|
697
|
+
return this;
|
|
698
|
+
}
|
|
699
|
+
get(key) {
|
|
700
|
+
return this.#weakMap.get(key)?.value;
|
|
701
|
+
}
|
|
702
|
+
delete(key) {
|
|
703
|
+
const entry = this.#weakMap.get(key);
|
|
704
|
+
if (!entry) return false;
|
|
705
|
+
this.#weakMap.delete(key);
|
|
706
|
+
this.#refSet.delete(entry.ref);
|
|
707
|
+
this.#finalizationGroup.unregister(entry.ref);
|
|
708
|
+
return true;
|
|
709
|
+
}
|
|
710
|
+
*[Symbol.iterator]() {
|
|
711
|
+
for (const ref of this.#refSet) {
|
|
712
|
+
const key = ref.deref();
|
|
713
|
+
if (!key) continue;
|
|
714
|
+
const entry = this.#weakMap.get(key);
|
|
715
|
+
if (entry) yield [key, entry.value];
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
entries() {
|
|
719
|
+
return this[Symbol.iterator]();
|
|
720
|
+
}
|
|
721
|
+
*keys() {
|
|
722
|
+
for (const [key] of this) yield key;
|
|
723
|
+
}
|
|
724
|
+
*values() {
|
|
725
|
+
for (const [, value] of this) yield value;
|
|
726
|
+
}
|
|
727
|
+
forEach(callback, thisArg) {
|
|
728
|
+
for (const [key, value] of this) callback.call(thisArg, value, key, this);
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
//#endregion
|
|
732
|
+
//#region src/annotation/injectable.ts
|
|
733
|
+
const _InjectableRegistry = /* @__PURE__ */ new WeakMap();
|
|
734
|
+
const _InjectableDeps = new IterableWeakMap();
|
|
735
|
+
/**
|
|
736
|
+
* Mark the class as an injectable to be handled by Sapling. The class can now be
|
|
737
|
+
* be injected into other classes, as well as allow the class to inject other `@Injectable` classes.
|
|
738
|
+
*
|
|
739
|
+
* @argument deps - An optional array to define any dependencies that this class may require.
|
|
740
|
+
*/
|
|
741
|
+
function Injectable(deps = []) {
|
|
742
|
+
return function(target) {
|
|
743
|
+
_InjectableRegistry.set(target, null);
|
|
744
|
+
_InjectableDeps.set(target, deps);
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* Resolves and instantiates a class along with all of it's transitive dependencies.
|
|
749
|
+
*
|
|
750
|
+
* Uses topological sort (Kahn's algorithm) to ensure that the dependency graph is created
|
|
751
|
+
* in a correct order.
|
|
752
|
+
*
|
|
753
|
+
* When `resolve` is first called (usually during controller registration),
|
|
754
|
+
* it will compute the dependency graph of all `@Injectable` classes and instantiates
|
|
755
|
+
* them in the correct order.
|
|
756
|
+
*
|
|
757
|
+
* Subsequent calls to dependencies that have already been resolved are cached, so they will
|
|
758
|
+
* re-use the created singletons instead of re-instantiation.
|
|
759
|
+
*/
|
|
760
|
+
function _resolve(ctor) {
|
|
761
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
762
|
+
const graph = /* @__PURE__ */ new Map();
|
|
763
|
+
_InjectableDeps.forEach((deps, node) => {
|
|
764
|
+
inDegree.set(node, inDegree.get(node) || 0);
|
|
765
|
+
deps.forEach((dep) => {
|
|
766
|
+
if (dep === void 0) throw new Error(`There is an @Injectable (${node.name}) which has a dependency that cannot be found. This is likely caused by a circular dependency.`);
|
|
767
|
+
inDegree.set(dep, inDegree.get(dep) || 0);
|
|
768
|
+
inDegree.set(node, inDegree.get(node) + 1);
|
|
769
|
+
if (!graph.has(dep)) graph.set(dep, []);
|
|
770
|
+
graph.get(dep).push(node);
|
|
771
|
+
});
|
|
772
|
+
});
|
|
773
|
+
const queue = [];
|
|
774
|
+
inDegree.forEach((deg, node) => {
|
|
775
|
+
if (deg === 0) queue.push(node);
|
|
776
|
+
});
|
|
777
|
+
while (queue.length) {
|
|
778
|
+
const current = queue.shift();
|
|
779
|
+
if (!_InjectableRegistry.get(current)) {
|
|
780
|
+
const instance = new current(...(_InjectableDeps.get(current) || []).map((dep) => _InjectableRegistry.get(dep)));
|
|
781
|
+
_InjectableRegistry.set(current, instance);
|
|
782
|
+
}
|
|
783
|
+
(graph.get(current) || []).forEach((neighbor) => {
|
|
784
|
+
inDegree.set(neighbor, (inDegree.get(neighbor) ?? 0) - 1);
|
|
785
|
+
if (inDegree.get(neighbor) === 0) queue.push(neighbor);
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
if (!_InjectableRegistry.get(ctor)) throw new Error("Circular dependency detected or injectable not registered");
|
|
789
|
+
return _InjectableRegistry.get(ctor);
|
|
790
|
+
}
|
|
791
|
+
//#endregion
|
|
690
792
|
//#region src/annotation/controller.ts
|
|
691
793
|
const _ControllerRegistry = /* @__PURE__ */ new WeakMap();
|
|
692
794
|
/**
|
|
@@ -698,6 +800,7 @@ const _ControllerRegistry = /* @__PURE__ */ new WeakMap();
|
|
|
698
800
|
function Controller({ prefix = "", deps = [] } = {}) {
|
|
699
801
|
return (target) => {
|
|
700
802
|
const targetClass = target;
|
|
803
|
+
_registerControllerClass(target, prefix);
|
|
701
804
|
const router = Router();
|
|
702
805
|
const routes = _getRoutes(target);
|
|
703
806
|
const usedRoutes = /* @__PURE__ */ new Set();
|
|
@@ -789,7 +892,7 @@ function __decorate(decorators, target, key, desc) {
|
|
|
789
892
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
790
893
|
}
|
|
791
894
|
//#endregion
|
|
792
|
-
//#region src/middleware/default/base.ts
|
|
895
|
+
//#region src/middleware/default/error/base.ts
|
|
793
896
|
let DefaultBaseErrorMiddleware = class DefaultBaseErrorMiddleware {
|
|
794
897
|
handle(err, _request, _response, _next) {
|
|
795
898
|
console.error("[Error]", err);
|
|
@@ -799,7 +902,17 @@ let DefaultBaseErrorMiddleware = class DefaultBaseErrorMiddleware {
|
|
|
799
902
|
__decorate([Middleware()], DefaultBaseErrorMiddleware.prototype, "handle", null);
|
|
800
903
|
DefaultBaseErrorMiddleware = __decorate([MiddlewareClass()], DefaultBaseErrorMiddleware);
|
|
801
904
|
//#endregion
|
|
802
|
-
//#region src/middleware/default/
|
|
905
|
+
//#region src/middleware/default/error/parse.ts
|
|
906
|
+
let DefaultParserErrorMiddleware = class DefaultParserErrorMiddleware {
|
|
907
|
+
handle(err, _request, _response, next) {
|
|
908
|
+
if (err instanceof ParserError) return ResponseEntity.status(err.status).body({ message: err.message });
|
|
909
|
+
next(err);
|
|
910
|
+
}
|
|
911
|
+
};
|
|
912
|
+
__decorate([Middleware()], DefaultParserErrorMiddleware.prototype, "handle", null);
|
|
913
|
+
DefaultParserErrorMiddleware = __decorate([MiddlewareClass()], DefaultParserErrorMiddleware);
|
|
914
|
+
//#endregion
|
|
915
|
+
//#region src/middleware/default/error/responsestatus.ts
|
|
803
916
|
let DefaultResponseStatusErrorMiddleware = class DefaultResponseStatusErrorMiddleware {
|
|
804
917
|
handle(err, _request, _response, next) {
|
|
805
918
|
if (err instanceof ResponseStatusError) return ResponseEntity.status(err.status).body({ message: err.message });
|
|
@@ -809,4 +922,39 @@ let DefaultResponseStatusErrorMiddleware = class DefaultResponseStatusErrorMiddl
|
|
|
809
922
|
__decorate([Middleware()], DefaultResponseStatusErrorMiddleware.prototype, "handle", null);
|
|
810
923
|
DefaultResponseStatusErrorMiddleware = __decorate([MiddlewareClass()], DefaultResponseStatusErrorMiddleware);
|
|
811
924
|
//#endregion
|
|
812
|
-
|
|
925
|
+
//#region src/middleware/default/openapi/index.ts
|
|
926
|
+
let DefaultOpenApiMiddleware = class DefaultOpenApiMiddleware {
|
|
927
|
+
handle(_request, _response, _next) {
|
|
928
|
+
return ResponseEntity.ok().body(_generateOpenApiSpec());
|
|
929
|
+
}
|
|
930
|
+
};
|
|
931
|
+
__decorate([GET(_settings.doc.openApiPath)], DefaultOpenApiMiddleware.prototype, "handle", null);
|
|
932
|
+
DefaultOpenApiMiddleware = __decorate([MiddlewareClass()], DefaultOpenApiMiddleware);
|
|
933
|
+
//#endregion
|
|
934
|
+
//#region src/middleware/default/swagger/index.ts
|
|
935
|
+
let Serve = class Serve {
|
|
936
|
+
constructor() {
|
|
937
|
+
this.handlers = swagger.serve;
|
|
938
|
+
}
|
|
939
|
+
handle(_request, _response, _next) {
|
|
940
|
+
return this.handlers;
|
|
941
|
+
}
|
|
942
|
+
};
|
|
943
|
+
__decorate([Middleware(_settings.doc.swaggerPath)], Serve.prototype, "handle", null);
|
|
944
|
+
Serve = __decorate([MiddlewareClass()], Serve);
|
|
945
|
+
let Setup = class Setup {
|
|
946
|
+
constructor() {
|
|
947
|
+
this.handler = swagger.setup(void 0, { swaggerOptions: { url: _settings.doc.openApiPath } });
|
|
948
|
+
}
|
|
949
|
+
handle(request, response, next) {
|
|
950
|
+
return this.handler(request, response, next);
|
|
951
|
+
}
|
|
952
|
+
};
|
|
953
|
+
__decorate([Middleware(_settings.doc.swaggerPath)], Setup.prototype, "handle", null);
|
|
954
|
+
Setup = __decorate([MiddlewareClass()], Setup);
|
|
955
|
+
const DefaultSwaggerMiddleware = {
|
|
956
|
+
Serve,
|
|
957
|
+
Setup
|
|
958
|
+
};
|
|
959
|
+
//#endregion
|
|
960
|
+
export { Controller, DELETE, DefaultBaseErrorMiddleware, DefaultOpenApiMiddleware, DefaultParserErrorMiddleware, DefaultResponseStatusErrorMiddleware, DefaultSwaggerMiddleware, GET, HEAD, Html404ErrorPage, HttpStatus, Injectable, Middleware, MiddlewareClass, OPTIONS, PATCH, POST, PUT, ParserError, RedirectView, RequestBody, RequestParam, RequestQuery, ResponseEntity, ResponseEntityBuilder, ResponseStatusError, Sapling, _ControllerRegistry, _InjectableDeps, _InjectableRegistry, _Route, _generateOpenApiSpec, _getRequestSchemas, _getRoutes, _parseOrThrow, _registerControllerClass, _resolve, _setOpenApiConfig, _settings, methodResolve, openApiGenerator };
|
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.23c37926",
|
|
4
4
|
"author": "Tahmid Ahmed",
|
|
5
5
|
"description": "A library to help you write cleaner Express.js code",
|
|
6
6
|
"repository": {
|
|
@@ -44,12 +44,14 @@
|
|
|
44
44
|
"@standard-schema/spec": "^1.1.0",
|
|
45
45
|
"@types/express": "^5",
|
|
46
46
|
"@types/supertest": "^7.2.0",
|
|
47
|
+
"@types/swagger-ui-express": "^4.1.8",
|
|
47
48
|
"@vitest/coverage-istanbul": "^4.1.2",
|
|
48
49
|
"eslint": "^10.1.0",
|
|
49
50
|
"eslint-plugin-perfectionist": "^5.7.0",
|
|
50
51
|
"globals": "^17.4.0",
|
|
51
52
|
"jiti": "^2.6.1",
|
|
52
53
|
"jsdom": "^29.0.1",
|
|
54
|
+
"openapi-types": "12.1.3",
|
|
53
55
|
"prettier": "^3.8.1",
|
|
54
56
|
"superjson": "^2.2.6",
|
|
55
57
|
"supertest": "^7.2.2",
|
|
@@ -60,6 +62,10 @@
|
|
|
60
62
|
"zod": "^4.4.3"
|
|
61
63
|
},
|
|
62
64
|
"inlinedDependencies": {
|
|
63
|
-
"@standard-schema/spec": "1.1.0"
|
|
65
|
+
"@standard-schema/spec": "1.1.0",
|
|
66
|
+
"openapi-types": "12.1.3"
|
|
67
|
+
},
|
|
68
|
+
"dependencies": {
|
|
69
|
+
"swagger-ui-express": "^5.0.1"
|
|
64
70
|
}
|
|
65
71
|
}
|