@gravito/core 3.0.0 → 3.0.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 +64 -25
- package/dist/Application.d.ts +2 -9
- package/dist/Container.d.ts +18 -1
- package/dist/GravitoServer.d.ts +8 -8
- package/dist/HookManager.d.ts +36 -34
- package/dist/PlanetCore.d.ts +48 -0
- package/dist/Route.d.ts +5 -0
- package/dist/Router.d.ts +14 -1
- package/dist/adapters/bun/BunContext.d.ts +1 -1
- package/dist/adapters/bun/BunNativeAdapter.d.ts +11 -1
- package/dist/adapters/bun/FastPathRegistry.d.ts +31 -0
- package/dist/adapters/bun/RadixNode.d.ts +4 -3
- package/dist/adapters/bun/RadixRouter.d.ts +2 -2
- package/dist/adapters/bun/types.d.ts +7 -0
- package/dist/adapters/types.d.ts +20 -0
- package/dist/compat/async-local-storage.d.ts +5 -1
- package/dist/compat/async-local-storage.js.map +2 -2
- package/dist/compat/crypto.d.ts +6 -1
- package/dist/compat/crypto.js.map +2 -2
- package/dist/engine/AOTRouter.d.ts +1 -1
- package/dist/engine/FastContext.d.ts +4 -4
- package/dist/engine/MinimalContext.d.ts +3 -3
- package/dist/engine/index.js +29 -8
- package/dist/engine/index.js.map +10 -10
- package/dist/engine/types.d.ts +5 -5
- package/dist/events/MessageQueueBridge.d.ts +2 -1
- package/dist/events/observability/EventMetrics.d.ts +1 -2
- package/dist/events/observability/ObservableHookManager.d.ts +1 -1
- package/dist/exceptions/AuthException.d.ts +11 -2
- package/dist/exceptions/AuthenticationException.d.ts +7 -1
- package/dist/exceptions/ContainerBindingCollisionException.d.ts +10 -0
- package/dist/exceptions/MiddlewareDriftException.d.ts +10 -0
- package/dist/exceptions/index.d.ts +3 -1
- package/dist/ffi/NativeAccelerator.js.map +3 -3
- package/dist/ffi/NativeHasher.d.ts +14 -0
- package/dist/ffi/NativeHasher.js +24 -1
- package/dist/ffi/NativeHasher.js.map +4 -4
- package/dist/ffi/cbor-fallback.js.map +1 -1
- package/dist/ffi/hash-fallback.d.ts +15 -0
- package/dist/ffi/hash-fallback.js +12 -1
- package/dist/ffi/hash-fallback.js.map +3 -3
- package/dist/ffi/types.d.ts +13 -0
- package/dist/ffi/types.js.map +1 -1
- package/dist/hooks/types.d.ts +7 -3
- package/dist/http/types.d.ts +2 -2
- package/dist/index.browser.d.ts +5 -5
- package/dist/index.browser.js +138 -17
- package/dist/index.browser.js.map +44 -42
- package/dist/index.d.ts +17 -7
- package/dist/index.js +588 -295
- package/dist/index.js.map +81 -77
- package/dist/runtime/NativeOrbitDetector.d.ts +59 -0
- package/dist/runtime/index.browser.d.ts +1 -1
- package/dist/runtime/index.d.ts +7 -0
- package/dist/runtime.d.ts +1 -1
- package/dist/testing/HttpTester.d.ts +4 -4
- package/dist/testing/TestResponse.d.ts +4 -4
- package/dist/types.d.ts +3 -3
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -1552,12 +1552,23 @@ var randomBytes = randomBytesFn;
|
|
|
1552
1552
|
import { createHash, createHmac } from "crypto";
|
|
1553
1553
|
|
|
1554
1554
|
class HashFallback {
|
|
1555
|
+
blake2bWarned = false;
|
|
1555
1556
|
sha256(input) {
|
|
1556
1557
|
return createHash("sha256").update(input).digest("hex");
|
|
1557
1558
|
}
|
|
1558
1559
|
hmacSha256(key, data) {
|
|
1559
1560
|
return createHmac("sha256", key).update(data).digest("hex");
|
|
1560
1561
|
}
|
|
1562
|
+
sha512(input) {
|
|
1563
|
+
return createHash("sha512").update(input).digest("hex");
|
|
1564
|
+
}
|
|
1565
|
+
blake2b(input) {
|
|
1566
|
+
if (!this.blake2bWarned) {
|
|
1567
|
+
console.warn("[gravito] BLAKE2b not available in node:crypto \u2014 using SHA-256 fallback");
|
|
1568
|
+
this.blake2bWarned = true;
|
|
1569
|
+
}
|
|
1570
|
+
return createHash("sha256").update(input).digest("hex");
|
|
1571
|
+
}
|
|
1561
1572
|
}
|
|
1562
1573
|
|
|
1563
1574
|
// src/ffi/NativeHasher.ts
|
|
@@ -1568,6 +1579,12 @@ class BunCryptoHasher {
|
|
|
1568
1579
|
hmacSha256(key, data) {
|
|
1569
1580
|
return new Bun.CryptoHasher("sha256", key).update(data).digest("hex");
|
|
1570
1581
|
}
|
|
1582
|
+
sha512(input) {
|
|
1583
|
+
return new Bun.CryptoHasher("sha512").update(input).digest("hex");
|
|
1584
|
+
}
|
|
1585
|
+
blake2b(input) {
|
|
1586
|
+
return new Bun.CryptoHasher("blake2b256").update(input).digest("hex");
|
|
1587
|
+
}
|
|
1571
1588
|
}
|
|
1572
1589
|
|
|
1573
1590
|
class NativeHasher {
|
|
@@ -1601,6 +1618,12 @@ class NativeHasher {
|
|
|
1601
1618
|
runtime
|
|
1602
1619
|
};
|
|
1603
1620
|
}
|
|
1621
|
+
static sha512(input) {
|
|
1622
|
+
return this.getAccelerator().sha512(input);
|
|
1623
|
+
}
|
|
1624
|
+
static blake2b(input) {
|
|
1625
|
+
return this.getAccelerator().blake2b(input);
|
|
1626
|
+
}
|
|
1604
1627
|
static sha256(input) {
|
|
1605
1628
|
return this.getAccelerator().sha256(input);
|
|
1606
1629
|
}
|
|
@@ -1648,6 +1671,7 @@ class RadixNode {
|
|
|
1648
1671
|
paramChild = null;
|
|
1649
1672
|
wildcardChild = null;
|
|
1650
1673
|
handlers = new Map;
|
|
1674
|
+
options = new Map;
|
|
1651
1675
|
paramName = null;
|
|
1652
1676
|
regex = null;
|
|
1653
1677
|
constructor(segment = "", type = 0 /* STATIC */) {
|
|
@@ -1661,13 +1685,15 @@ class RadixNode {
|
|
|
1661
1685
|
children: Array.from(this.children.entries()).map(([k, v]) => [k, v.toJSON()]),
|
|
1662
1686
|
paramChild: this.paramChild?.toJSON() || null,
|
|
1663
1687
|
wildcardChild: this.wildcardChild?.toJSON() || null,
|
|
1688
|
+
handlers: Array.from(this.handlers.entries()),
|
|
1689
|
+
options: Array.from(this.options.entries()),
|
|
1664
1690
|
paramName: this.paramName,
|
|
1665
1691
|
regex: this.regex ? this.regex.source : null
|
|
1666
1692
|
};
|
|
1667
1693
|
}
|
|
1668
1694
|
static fromJSON(json) {
|
|
1669
1695
|
const node = new RadixNode(json.segment, json.type);
|
|
1670
|
-
node.paramName = json.paramName;
|
|
1696
|
+
node.paramName = json.paramName ?? null;
|
|
1671
1697
|
if (json.regex) {
|
|
1672
1698
|
node.regex = new RegExp(json.regex);
|
|
1673
1699
|
}
|
|
@@ -1682,6 +1708,16 @@ class RadixNode {
|
|
|
1682
1708
|
if (json.wildcardChild) {
|
|
1683
1709
|
node.wildcardChild = RadixNode.fromJSON(json.wildcardChild);
|
|
1684
1710
|
}
|
|
1711
|
+
if (json.handlers) {
|
|
1712
|
+
for (const [method, handlers] of json.handlers) {
|
|
1713
|
+
node.handlers.set(method, handlers);
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
if (json.options) {
|
|
1717
|
+
for (const [method, options2] of json.options) {
|
|
1718
|
+
node.options.set(method, options2);
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1685
1721
|
return node;
|
|
1686
1722
|
}
|
|
1687
1723
|
}
|
|
@@ -1717,7 +1753,7 @@ class RadixRouter {
|
|
|
1717
1753
|
where(param, regex) {
|
|
1718
1754
|
this.globalConstraints.set(param, regex);
|
|
1719
1755
|
}
|
|
1720
|
-
add(method, path2, handlers) {
|
|
1756
|
+
add(method, path2, handlers, options2) {
|
|
1721
1757
|
let node = this.root;
|
|
1722
1758
|
const segments = this.splitPath(path2);
|
|
1723
1759
|
for (let i = 0;i < segments.length; i++) {
|
|
@@ -1747,7 +1783,11 @@ class RadixRouter {
|
|
|
1747
1783
|
node = node.children.get(segment);
|
|
1748
1784
|
}
|
|
1749
1785
|
}
|
|
1750
|
-
|
|
1786
|
+
const normalizedMethod = method.toLowerCase();
|
|
1787
|
+
node.handlers.set(normalizedMethod, handlers);
|
|
1788
|
+
if (options2) {
|
|
1789
|
+
node.options.set(normalizedMethod, options2);
|
|
1790
|
+
}
|
|
1751
1791
|
this.routeCache.clear();
|
|
1752
1792
|
}
|
|
1753
1793
|
match(method, path2) {
|
|
@@ -1755,7 +1795,7 @@ class RadixRouter {
|
|
|
1755
1795
|
if (path2 === "/" || path2 === "") {
|
|
1756
1796
|
const handlers = this.root.handlers.get(normalizedMethod);
|
|
1757
1797
|
if (handlers) {
|
|
1758
|
-
return { handlers, params: {} };
|
|
1798
|
+
return { handlers, params: {}, options: this.root.options.get(normalizedMethod) };
|
|
1759
1799
|
}
|
|
1760
1800
|
return null;
|
|
1761
1801
|
}
|
|
@@ -1772,11 +1812,13 @@ class RadixRouter {
|
|
|
1772
1812
|
matchRecursive(node, segments, depth, params, method) {
|
|
1773
1813
|
if (depth >= segments.length) {
|
|
1774
1814
|
let handlers = node.handlers.get(method);
|
|
1815
|
+
let options2 = node.options.get(method);
|
|
1775
1816
|
if (!handlers) {
|
|
1776
1817
|
handlers = node.handlers.get("all");
|
|
1818
|
+
options2 = node.options.get("all");
|
|
1777
1819
|
}
|
|
1778
1820
|
if (handlers) {
|
|
1779
|
-
return { handlers, params };
|
|
1821
|
+
return { handlers, params, options: options2 };
|
|
1780
1822
|
}
|
|
1781
1823
|
return null;
|
|
1782
1824
|
}
|
|
@@ -1803,11 +1845,13 @@ class RadixRouter {
|
|
|
1803
1845
|
}
|
|
1804
1846
|
if (node.wildcardChild) {
|
|
1805
1847
|
let handlers = node.wildcardChild.handlers.get(method);
|
|
1848
|
+
let options2 = node.wildcardChild.options.get(method);
|
|
1806
1849
|
if (!handlers) {
|
|
1807
1850
|
handlers = node.wildcardChild.handlers.get("all");
|
|
1851
|
+
options2 = node.wildcardChild.options.get("all");
|
|
1808
1852
|
}
|
|
1809
1853
|
if (handlers) {
|
|
1810
|
-
return { handlers, params };
|
|
1854
|
+
return { handlers, params, options: options2 };
|
|
1811
1855
|
}
|
|
1812
1856
|
}
|
|
1813
1857
|
return null;
|
|
@@ -2289,7 +2333,7 @@ class RequestScopeManager {
|
|
|
2289
2333
|
let servicesCleaned = 0;
|
|
2290
2334
|
for (const [, instance] of this.scoped) {
|
|
2291
2335
|
if (instance && typeof instance === "object" && "cleanup" in instance) {
|
|
2292
|
-
const fn = instance
|
|
2336
|
+
const fn = instance["cleanup"];
|
|
2293
2337
|
if (typeof fn === "function") {
|
|
2294
2338
|
try {
|
|
2295
2339
|
await fn.call(instance);
|
|
@@ -3300,7 +3344,7 @@ class Gravito {
|
|
|
3300
3344
|
// package.json
|
|
3301
3345
|
var package_default = {
|
|
3302
3346
|
name: "@gravito/core",
|
|
3303
|
-
version: "3.0.
|
|
3347
|
+
version: "3.0.1",
|
|
3304
3348
|
description: "",
|
|
3305
3349
|
module: "./dist/index.js",
|
|
3306
3350
|
main: "./dist/index.js",
|
|
@@ -3309,9 +3353,9 @@ var package_default = {
|
|
|
3309
3353
|
types: "./dist/index.d.ts",
|
|
3310
3354
|
exports: {
|
|
3311
3355
|
".": {
|
|
3356
|
+
types: "./dist/index.d.ts",
|
|
3312
3357
|
browser: "./dist/index.browser.js",
|
|
3313
3358
|
bun: "./dist/index.js",
|
|
3314
|
-
types: "./dist/index.d.ts",
|
|
3315
3359
|
default: "./dist/index.js"
|
|
3316
3360
|
},
|
|
3317
3361
|
"./compat": {
|
|
@@ -3357,7 +3401,8 @@ var package_default = {
|
|
|
3357
3401
|
typecheck: "bun tsc -p tsconfig.json --noEmit --skipLibCheck",
|
|
3358
3402
|
prepublishOnly: "bun run typecheck && bun run test && bun run build",
|
|
3359
3403
|
"test:unit": "bun test $(find tests -name '*.test.ts' ! -name '*.integration.test.ts' 2>/dev/null | tr '\\n' ' ') --timeout=10000",
|
|
3360
|
-
"test:integration": "test $(find tests -name '*.integration.test.ts' 2>/dev/null | wc -l) -gt 0 && find tests -name '*.integration.test.ts' -print0 | xargs -0 bun test --timeout=10000 || echo 'No integration tests found'"
|
|
3404
|
+
"test:integration": "test $(find tests -name '*.integration.test.ts' 2>/dev/null | wc -l) -gt 0 && find tests -name '*.integration.test.ts' -print0 | xargs -0 bun test --timeout=10000 || echo 'No integration tests found'",
|
|
3405
|
+
publint: "publint"
|
|
3361
3406
|
},
|
|
3362
3407
|
keywords: [],
|
|
3363
3408
|
author: "Carl Lee <carllee0520@gmail.com>",
|
|
@@ -3755,6 +3800,250 @@ class BunWebSocketHandler {
|
|
|
3755
3800
|
}
|
|
3756
3801
|
}
|
|
3757
3802
|
|
|
3803
|
+
// src/adapters/bun/FastPathRegistry.ts
|
|
3804
|
+
class FastPathRegistry {
|
|
3805
|
+
routes = new Map;
|
|
3806
|
+
register(method, path2, handler) {
|
|
3807
|
+
const upperMethod = method.toUpperCase();
|
|
3808
|
+
let methodRoutes = this.routes.get(upperMethod);
|
|
3809
|
+
if (!methodRoutes) {
|
|
3810
|
+
methodRoutes = new Map;
|
|
3811
|
+
this.routes.set(upperMethod, methodRoutes);
|
|
3812
|
+
}
|
|
3813
|
+
methodRoutes.set(path2, handler);
|
|
3814
|
+
}
|
|
3815
|
+
match(method, path2) {
|
|
3816
|
+
const methodRoutes = this.routes.get(method.toUpperCase());
|
|
3817
|
+
if (!methodRoutes) {
|
|
3818
|
+
return;
|
|
3819
|
+
}
|
|
3820
|
+
return methodRoutes.get(path2);
|
|
3821
|
+
}
|
|
3822
|
+
getAll() {
|
|
3823
|
+
return this.routes;
|
|
3824
|
+
}
|
|
3825
|
+
}
|
|
3826
|
+
|
|
3827
|
+
// src/exceptions/GravitoException.ts
|
|
3828
|
+
class GravitoException extends Error {
|
|
3829
|
+
status;
|
|
3830
|
+
code;
|
|
3831
|
+
i18nKey;
|
|
3832
|
+
i18nParams;
|
|
3833
|
+
constructor(status, code, options2 = {}) {
|
|
3834
|
+
super(options2.message);
|
|
3835
|
+
this.name = "GravitoException";
|
|
3836
|
+
this.status = status;
|
|
3837
|
+
this.cause = options2.cause;
|
|
3838
|
+
this.code = code;
|
|
3839
|
+
if (options2.i18nKey) {
|
|
3840
|
+
this.i18nKey = options2.i18nKey;
|
|
3841
|
+
}
|
|
3842
|
+
if (options2.i18nParams) {
|
|
3843
|
+
this.i18nParams = options2.i18nParams;
|
|
3844
|
+
}
|
|
3845
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
3846
|
+
}
|
|
3847
|
+
getLocalizedMessage(t) {
|
|
3848
|
+
if (this.i18nKey) {
|
|
3849
|
+
return t(this.i18nKey, this.i18nParams);
|
|
3850
|
+
}
|
|
3851
|
+
return this.message;
|
|
3852
|
+
}
|
|
3853
|
+
}
|
|
3854
|
+
|
|
3855
|
+
// src/exceptions/DomainException.ts
|
|
3856
|
+
class DomainException extends GravitoException {
|
|
3857
|
+
constructor(status, code, options2 = {}) {
|
|
3858
|
+
super(status, code, options2);
|
|
3859
|
+
this.name = "DomainException";
|
|
3860
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
3861
|
+
}
|
|
3862
|
+
}
|
|
3863
|
+
|
|
3864
|
+
// src/exceptions/AuthException.ts
|
|
3865
|
+
class AuthException extends DomainException {
|
|
3866
|
+
constructor(status, code, options2 = {}) {
|
|
3867
|
+
super(status, code, options2);
|
|
3868
|
+
this.name = "AuthException";
|
|
3869
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
|
|
3873
|
+
// src/exceptions/AuthenticationException.ts
|
|
3874
|
+
class AuthenticationException extends DomainException {
|
|
3875
|
+
constructor(message = "Unauthenticated.") {
|
|
3876
|
+
super(401, "UNAUTHENTICATED", {
|
|
3877
|
+
message,
|
|
3878
|
+
i18nKey: "errors.authentication.unauthenticated"
|
|
3879
|
+
});
|
|
3880
|
+
this.name = "AuthenticationException";
|
|
3881
|
+
}
|
|
3882
|
+
}
|
|
3883
|
+
|
|
3884
|
+
// src/exceptions/AuthorizationException.ts
|
|
3885
|
+
class AuthorizationException extends DomainException {
|
|
3886
|
+
constructor(message = "This action is unauthorized.") {
|
|
3887
|
+
super(403, "FORBIDDEN", {
|
|
3888
|
+
message,
|
|
3889
|
+
i18nKey: "errors.authorization.forbidden"
|
|
3890
|
+
});
|
|
3891
|
+
this.name = "AuthorizationException";
|
|
3892
|
+
}
|
|
3893
|
+
}
|
|
3894
|
+
|
|
3895
|
+
// src/exceptions/InfrastructureException.ts
|
|
3896
|
+
class InfrastructureException extends GravitoException {
|
|
3897
|
+
retryable;
|
|
3898
|
+
constructor(status, code, options2 = {}) {
|
|
3899
|
+
super(status, code, options2);
|
|
3900
|
+
this.name = "InfrastructureException";
|
|
3901
|
+
this.retryable = options2.retryable ?? false;
|
|
3902
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
3903
|
+
}
|
|
3904
|
+
}
|
|
3905
|
+
|
|
3906
|
+
// src/exceptions/CacheException.ts
|
|
3907
|
+
class CacheException extends InfrastructureException {
|
|
3908
|
+
constructor(status, code, options2 = {}) {
|
|
3909
|
+
super(status, code, options2);
|
|
3910
|
+
this.name = "CacheException";
|
|
3911
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
3912
|
+
}
|
|
3913
|
+
}
|
|
3914
|
+
|
|
3915
|
+
// src/exceptions/SystemException.ts
|
|
3916
|
+
class SystemException extends GravitoException {
|
|
3917
|
+
constructor(status, code, options2 = {}) {
|
|
3918
|
+
super(status, code, options2);
|
|
3919
|
+
this.name = "SystemException";
|
|
3920
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
3921
|
+
}
|
|
3922
|
+
}
|
|
3923
|
+
|
|
3924
|
+
// src/exceptions/CircularDependencyException.ts
|
|
3925
|
+
class CircularDependencyException extends SystemException {
|
|
3926
|
+
constructor(key, stack) {
|
|
3927
|
+
const path2 = [...stack, key].map(String).join(" -> ");
|
|
3928
|
+
super(500, "system.circular_dependency", {
|
|
3929
|
+
message: `Circular dependency detected: ${path2}`
|
|
3930
|
+
});
|
|
3931
|
+
this.name = "CircularDependencyException";
|
|
3932
|
+
}
|
|
3933
|
+
}
|
|
3934
|
+
|
|
3935
|
+
// src/exceptions/ConfigurationException.ts
|
|
3936
|
+
class ConfigurationException extends SystemException {
|
|
3937
|
+
constructor(message, options2 = {}) {
|
|
3938
|
+
super(500, "system.configuration_error", { ...options2, message });
|
|
3939
|
+
this.name = "ConfigurationException";
|
|
3940
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
3941
|
+
}
|
|
3942
|
+
}
|
|
3943
|
+
|
|
3944
|
+
// src/exceptions/ContainerBindingCollisionException.ts
|
|
3945
|
+
class ContainerBindingCollisionException extends SystemException {
|
|
3946
|
+
constructor(message, options2 = {}) {
|
|
3947
|
+
super(500, "system.container_binding_collision", { ...options2, message });
|
|
3948
|
+
this.name = "ContainerBindingCollisionException";
|
|
3949
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
3950
|
+
}
|
|
3951
|
+
}
|
|
3952
|
+
|
|
3953
|
+
// src/exceptions/DatabaseException.ts
|
|
3954
|
+
class DatabaseException extends InfrastructureException {
|
|
3955
|
+
constructor(status, code, options2 = {}) {
|
|
3956
|
+
super(status, code, options2);
|
|
3957
|
+
this.name = "DatabaseException";
|
|
3958
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
3959
|
+
}
|
|
3960
|
+
}
|
|
3961
|
+
|
|
3962
|
+
// src/exceptions/HttpException.ts
|
|
3963
|
+
class HttpException extends GravitoException {
|
|
3964
|
+
constructor(status, options2 = {}) {
|
|
3965
|
+
super(status, "HTTP_ERROR", options2);
|
|
3966
|
+
this.name = "HttpException";
|
|
3967
|
+
}
|
|
3968
|
+
}
|
|
3969
|
+
|
|
3970
|
+
// src/exceptions/MiddlewareDriftException.ts
|
|
3971
|
+
class MiddlewareDriftException extends SystemException {
|
|
3972
|
+
constructor(message, options2 = {}) {
|
|
3973
|
+
super(500, "system.middleware_drift", { ...options2, message });
|
|
3974
|
+
this.name = "MiddlewareDriftException";
|
|
3975
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
3976
|
+
}
|
|
3977
|
+
}
|
|
3978
|
+
|
|
3979
|
+
// src/exceptions/ModelNotFoundException.ts
|
|
3980
|
+
class ModelNotFoundException extends GravitoException {
|
|
3981
|
+
model;
|
|
3982
|
+
id;
|
|
3983
|
+
constructor(model, id) {
|
|
3984
|
+
super(404, "NOT_FOUND", {
|
|
3985
|
+
message: `${model} not found.`,
|
|
3986
|
+
i18nKey: "errors.model.not_found",
|
|
3987
|
+
i18nParams: { model, id: String(id ?? "") }
|
|
3988
|
+
});
|
|
3989
|
+
this.name = "ModelNotFoundException";
|
|
3990
|
+
this.model = model;
|
|
3991
|
+
if (id !== undefined) {
|
|
3992
|
+
this.id = id;
|
|
3993
|
+
}
|
|
3994
|
+
}
|
|
3995
|
+
}
|
|
3996
|
+
|
|
3997
|
+
// src/exceptions/QueueException.ts
|
|
3998
|
+
class QueueException extends InfrastructureException {
|
|
3999
|
+
constructor(status, code, options2 = {}) {
|
|
4000
|
+
super(status, code, options2);
|
|
4001
|
+
this.name = "QueueException";
|
|
4002
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
4003
|
+
}
|
|
4004
|
+
}
|
|
4005
|
+
|
|
4006
|
+
// src/exceptions/StorageException.ts
|
|
4007
|
+
class StorageException extends InfrastructureException {
|
|
4008
|
+
constructor(status, code, options2 = {}) {
|
|
4009
|
+
super(status, code, options2);
|
|
4010
|
+
this.name = "StorageException";
|
|
4011
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
4012
|
+
}
|
|
4013
|
+
}
|
|
4014
|
+
|
|
4015
|
+
// src/exceptions/StreamException.ts
|
|
4016
|
+
class StreamException extends InfrastructureException {
|
|
4017
|
+
constructor(status, code, options2 = {}) {
|
|
4018
|
+
super(status, code, options2);
|
|
4019
|
+
this.name = "StreamException";
|
|
4020
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
|
|
4024
|
+
// src/exceptions/ValidationException.ts
|
|
4025
|
+
class ValidationException extends DomainException {
|
|
4026
|
+
errors;
|
|
4027
|
+
redirectTo;
|
|
4028
|
+
input;
|
|
4029
|
+
constructor(errors, message = "Validation failed") {
|
|
4030
|
+
super(422, "VALIDATION_ERROR", {
|
|
4031
|
+
message,
|
|
4032
|
+
i18nKey: "errors.validation.failed"
|
|
4033
|
+
});
|
|
4034
|
+
this.name = "ValidationException";
|
|
4035
|
+
this.errors = errors;
|
|
4036
|
+
}
|
|
4037
|
+
withRedirect(url) {
|
|
4038
|
+
this.redirectTo = url;
|
|
4039
|
+
return this;
|
|
4040
|
+
}
|
|
4041
|
+
withInput(input) {
|
|
4042
|
+
this.input = input;
|
|
4043
|
+
return this;
|
|
4044
|
+
}
|
|
4045
|
+
}
|
|
4046
|
+
|
|
3758
4047
|
// src/adapters/bun/BunNativeAdapter.ts
|
|
3759
4048
|
class BunNativeAdapter {
|
|
3760
4049
|
name = "bun-native";
|
|
@@ -3762,7 +4051,9 @@ class BunNativeAdapter {
|
|
|
3762
4051
|
get native() {
|
|
3763
4052
|
return this;
|
|
3764
4053
|
}
|
|
4054
|
+
isSnapshotLocked = false;
|
|
3765
4055
|
router = new RadixRouter;
|
|
4056
|
+
fastPathRegistry = new FastPathRegistry;
|
|
3766
4057
|
middlewares = [];
|
|
3767
4058
|
errorHandler = null;
|
|
3768
4059
|
notFoundHandler = null;
|
|
@@ -3770,22 +4061,41 @@ class BunNativeAdapter {
|
|
|
3770
4061
|
maxPoolSize = 100;
|
|
3771
4062
|
middlewareChainCache = new Map;
|
|
3772
4063
|
wsHandler = new BunWebSocketHandler;
|
|
4064
|
+
checkLock() {
|
|
4065
|
+
if (this.isSnapshotLocked && true) {
|
|
4066
|
+
throw new MiddlewareDriftException("FAST_PATH_MIDDLEWARE_DRIFT: Middleware or routes cannot be added after serveConfig() has been called. " + "This ensures the snapshotted configuration remains consistent with the application state.");
|
|
4067
|
+
}
|
|
4068
|
+
}
|
|
3773
4069
|
route(method, path2, ...handlers) {
|
|
3774
|
-
this.
|
|
4070
|
+
this.checkLock();
|
|
4071
|
+
const last = handlers[handlers.length - 1];
|
|
4072
|
+
let options2;
|
|
4073
|
+
if (last && typeof last === "object" && !Array.isArray(last) && "excludeMiddleware" in last) {
|
|
4074
|
+
options2 = handlers.pop();
|
|
4075
|
+
}
|
|
4076
|
+
this.router.add(method, path2, handlers, options2);
|
|
3775
4077
|
}
|
|
3776
4078
|
routes(routes) {
|
|
4079
|
+
this.checkLock();
|
|
3777
4080
|
for (const route of routes) {
|
|
3778
|
-
|
|
4081
|
+
const options2 = {};
|
|
4082
|
+
if (route.excludeMiddleware) {
|
|
4083
|
+
options2.excludeMiddleware = route.excludeMiddleware;
|
|
4084
|
+
}
|
|
4085
|
+
this.router.add(route.method, route.path, route.handlers, Object.keys(options2).length > 0 ? options2 : undefined);
|
|
3779
4086
|
}
|
|
3780
4087
|
}
|
|
3781
4088
|
use(path2, ...middleware) {
|
|
4089
|
+
this.checkLock();
|
|
3782
4090
|
this.middlewares.push({ path: path2, handlers: middleware });
|
|
3783
4091
|
this.middlewareChainCache.clear();
|
|
3784
4092
|
}
|
|
3785
4093
|
useGlobal(...middleware) {
|
|
4094
|
+
this.checkLock();
|
|
3786
4095
|
this.use("*", ...middleware);
|
|
3787
4096
|
}
|
|
3788
4097
|
useScoped(scope, path2, ...middleware) {
|
|
4098
|
+
this.checkLock();
|
|
3789
4099
|
if (path2 === "*" || path2 === "*/*") {
|
|
3790
4100
|
throw new Error(`useScoped(): Cannot use wildcard path '*' in Orbit-scoped middleware. ` + `Use regular use('*') for global middleware, or specify explicit paths like '${scope}/*'`);
|
|
3791
4101
|
}
|
|
@@ -3800,6 +4110,9 @@ class BunNativeAdapter {
|
|
|
3800
4110
|
if (pattern === "*") {
|
|
3801
4111
|
return true;
|
|
3802
4112
|
}
|
|
4113
|
+
if (pattern === "/") {
|
|
4114
|
+
return true;
|
|
4115
|
+
}
|
|
3803
4116
|
if (pattern.endsWith("/*")) {
|
|
3804
4117
|
const basePattern = pattern.slice(0, -2);
|
|
3805
4118
|
return path2 === basePattern || path2.startsWith(`${basePattern}/`);
|
|
@@ -3810,17 +4123,25 @@ class BunNativeAdapter {
|
|
|
3810
4123
|
}
|
|
3811
4124
|
return path2 === pattern || path2.startsWith(`${pattern}/`);
|
|
3812
4125
|
}
|
|
3813
|
-
getCompiledMiddlewareChain(path2) {
|
|
3814
|
-
|
|
3815
|
-
|
|
4126
|
+
getCompiledMiddlewareChain(path2, options2) {
|
|
4127
|
+
const exclude = options2?.excludeMiddleware || [];
|
|
4128
|
+
const cacheKey = exclude.length > 0 ? `${path2}:exclude:${exclude.sort().join(",")}` : path2;
|
|
4129
|
+
if (this.middlewareChainCache.has(cacheKey)) {
|
|
4130
|
+
return this.middlewareChainCache.get(cacheKey);
|
|
3816
4131
|
}
|
|
3817
4132
|
const chain = [];
|
|
3818
4133
|
for (const mw of this.middlewares) {
|
|
3819
4134
|
if (this.matchesPath(mw.path, path2)) {
|
|
3820
|
-
|
|
4135
|
+
for (const handler of mw.handlers) {
|
|
4136
|
+
const name = handler.name || handler.middlewareName;
|
|
4137
|
+
if (name && exclude.includes(name)) {
|
|
4138
|
+
continue;
|
|
4139
|
+
}
|
|
4140
|
+
chain.push(handler);
|
|
4141
|
+
}
|
|
3821
4142
|
}
|
|
3822
4143
|
}
|
|
3823
|
-
this.middlewareChainCache.set(
|
|
4144
|
+
this.middlewareChainCache.set(cacheKey, chain);
|
|
3824
4145
|
return chain;
|
|
3825
4146
|
}
|
|
3826
4147
|
acquireContext(request) {
|
|
@@ -3862,12 +4183,36 @@ class BunNativeAdapter {
|
|
|
3862
4183
|
return BunContext.create(request);
|
|
3863
4184
|
}
|
|
3864
4185
|
onError(handler) {
|
|
4186
|
+
this.checkLock();
|
|
3865
4187
|
this.errorHandler = handler;
|
|
3866
4188
|
}
|
|
3867
4189
|
onNotFound(handler) {
|
|
4190
|
+
this.checkLock();
|
|
3868
4191
|
this.notFoundHandler = handler;
|
|
3869
4192
|
}
|
|
4193
|
+
registerFastPath(method, path2, handler) {
|
|
4194
|
+
this.checkLock();
|
|
4195
|
+
this.fastPathRegistry.register(method, path2, handler);
|
|
4196
|
+
}
|
|
4197
|
+
serveConfig(baseConfig = {}) {
|
|
4198
|
+
this.isSnapshotLocked = true;
|
|
4199
|
+
const routes = {};
|
|
4200
|
+
for (const [method, pathMap] of this.fastPathRegistry.getAll()) {
|
|
4201
|
+
if (method === "GET") {
|
|
4202
|
+
for (const [path2, handler] of pathMap) {
|
|
4203
|
+
routes[path2] = handler;
|
|
4204
|
+
}
|
|
4205
|
+
}
|
|
4206
|
+
}
|
|
4207
|
+
return {
|
|
4208
|
+
...baseConfig,
|
|
4209
|
+
routes,
|
|
4210
|
+
fetch: this.fetch.bind(this),
|
|
4211
|
+
websocket: this.websocket
|
|
4212
|
+
};
|
|
4213
|
+
}
|
|
3870
4214
|
registerWebSocketRoute(path2, handlers) {
|
|
4215
|
+
this.checkLock();
|
|
3871
4216
|
this.wsHandler.register(path2, handlers);
|
|
3872
4217
|
}
|
|
3873
4218
|
get websocket() {
|
|
@@ -3882,7 +4227,12 @@ class BunNativeAdapter {
|
|
|
3882
4227
|
}
|
|
3883
4228
|
async fetch(request, _server) {
|
|
3884
4229
|
const url = new URL(request.url);
|
|
3885
|
-
|
|
4230
|
+
const path2 = url.pathname;
|
|
4231
|
+
const fastHandler = this.fastPathRegistry.match(request.method, path2);
|
|
4232
|
+
if (fastHandler) {
|
|
4233
|
+
return fastHandler(request);
|
|
4234
|
+
}
|
|
4235
|
+
if (_server != null && typeof _server.upgrade === "function" && request.headers.get("upgrade")?.toLowerCase() === "websocket" && this.wsHandler.hasRoute(path2)) {
|
|
3886
4236
|
const upgraded = _server.upgrade(request, {
|
|
3887
4237
|
data: {
|
|
3888
4238
|
path: url.pathname,
|
|
@@ -3896,11 +4246,10 @@ class BunNativeAdapter {
|
|
|
3896
4246
|
}
|
|
3897
4247
|
const ctx = this.acquireContext(request);
|
|
3898
4248
|
try {
|
|
3899
|
-
const path2 = url.pathname;
|
|
3900
4249
|
const method = request.method;
|
|
3901
4250
|
const match = this.router.match(method, path2);
|
|
3902
4251
|
const handlers = [];
|
|
3903
|
-
const middlewareChain = this.getCompiledMiddlewareChain(path2);
|
|
4252
|
+
const middlewareChain = this.getCompiledMiddlewareChain(path2, match?.options);
|
|
3904
4253
|
handlers.push(...middlewareChain);
|
|
3905
4254
|
if (match) {
|
|
3906
4255
|
if (match.params) {
|
|
@@ -4608,7 +4957,8 @@ function createNodeAdapter() {
|
|
|
4608
4957
|
},
|
|
4609
4958
|
resourceUsage: async () => {
|
|
4610
4959
|
try {
|
|
4611
|
-
const
|
|
4960
|
+
const childWithUsage = child;
|
|
4961
|
+
const usage = childWithUsage.resourceUsage?.();
|
|
4612
4962
|
if (!usage) {
|
|
4613
4963
|
return;
|
|
4614
4964
|
}
|
|
@@ -4815,8 +5165,80 @@ function createUnknownAdapter() {
|
|
|
4815
5165
|
serve() {
|
|
4816
5166
|
throw new Error("[RuntimeAdapter] Unsupported runtime for serve()");
|
|
4817
5167
|
}
|
|
4818
|
-
};
|
|
5168
|
+
};
|
|
5169
|
+
}
|
|
5170
|
+
// src/runtime/NativeOrbitDetector.ts
|
|
5171
|
+
function probeCryptoHasher(CryptoHasherCtor, algo) {
|
|
5172
|
+
try {
|
|
5173
|
+
const ctor = CryptoHasherCtor;
|
|
5174
|
+
new ctor(algo).update("").digest("hex");
|
|
5175
|
+
return true;
|
|
5176
|
+
} catch {
|
|
5177
|
+
return false;
|
|
5178
|
+
}
|
|
5179
|
+
}
|
|
5180
|
+
|
|
5181
|
+
class NativeOrbitDetector {
|
|
5182
|
+
static cached = null;
|
|
5183
|
+
static detectBunCapabilities() {
|
|
5184
|
+
if (this.cached !== null) {
|
|
5185
|
+
return this.cached;
|
|
5186
|
+
}
|
|
5187
|
+
const kind2 = getRuntimeKind();
|
|
5188
|
+
const B2 = globalThis.Bun;
|
|
5189
|
+
if (kind2 !== "bun" || !B2) {
|
|
5190
|
+
this.cached = Object.freeze({
|
|
5191
|
+
runtime: kind2,
|
|
5192
|
+
bunVersion: null,
|
|
5193
|
+
password: Object.freeze({ available: false, argon2id: false, bcrypt: false }),
|
|
5194
|
+
cryptoHasher: Object.freeze({
|
|
5195
|
+
available: false,
|
|
5196
|
+
sha256: false,
|
|
5197
|
+
sha512: false,
|
|
5198
|
+
blake2b: false
|
|
5199
|
+
}),
|
|
5200
|
+
glob: false
|
|
5201
|
+
});
|
|
5202
|
+
return this.cached;
|
|
5203
|
+
}
|
|
5204
|
+
const hasPassword = typeof B2.password?.hash === "function" && typeof B2.password?.verify === "function";
|
|
5205
|
+
const passwordFeatures = Object.freeze({
|
|
5206
|
+
available: hasPassword,
|
|
5207
|
+
argon2id: hasPassword,
|
|
5208
|
+
bcrypt: hasPassword
|
|
5209
|
+
});
|
|
5210
|
+
const HasherCtor = B2.CryptoHasher;
|
|
5211
|
+
const hasHasher = typeof HasherCtor === "function";
|
|
5212
|
+
const sha256 = hasHasher ? probeCryptoHasher(HasherCtor, "sha256") : false;
|
|
5213
|
+
const sha512 = hasHasher ? probeCryptoHasher(HasherCtor, "sha512") : false;
|
|
5214
|
+
const blake2b = hasHasher ? probeCryptoHasher(HasherCtor, "blake2b256") : false;
|
|
5215
|
+
const cryptoHasherFeatures = Object.freeze({
|
|
5216
|
+
available: hasHasher && sha256,
|
|
5217
|
+
sha256,
|
|
5218
|
+
sha512,
|
|
5219
|
+
blake2b
|
|
5220
|
+
});
|
|
5221
|
+
const hasGlob = typeof B2.Glob === "function";
|
|
5222
|
+
this.cached = Object.freeze({
|
|
5223
|
+
runtime: kind2,
|
|
5224
|
+
bunVersion: B2.version ?? null,
|
|
5225
|
+
password: passwordFeatures,
|
|
5226
|
+
cryptoHasher: cryptoHasherFeatures,
|
|
5227
|
+
glob: hasGlob
|
|
5228
|
+
});
|
|
5229
|
+
return this.cached;
|
|
5230
|
+
}
|
|
5231
|
+
static reset() {
|
|
5232
|
+
this.cached = null;
|
|
5233
|
+
}
|
|
4819
5234
|
}
|
|
5235
|
+
function formatCapabilityReport(f) {
|
|
5236
|
+
const passwordPart = f.password.argon2id ? "Bun.password argon2id \u2713" : "Bun.password argon2id \u2717 (fallback: none)";
|
|
5237
|
+
const hasherPart = f.cryptoHasher.available ? "Bun.CryptoHasher \u2713" : "Bun.CryptoHasher \u2717 (fallback: node:crypto)";
|
|
5238
|
+
const globPart = f.glob ? "Bun.Glob \u2713" : "Bun.Glob \u2717 (fallback: node:fs glob)";
|
|
5239
|
+
return `[gravito] native: ${passwordPart}, ${hasherPart}, ${globPart}`;
|
|
5240
|
+
}
|
|
5241
|
+
|
|
4820
5242
|
// src/runtime/archive.ts
|
|
4821
5243
|
function createBunArchiveAdapter() {
|
|
4822
5244
|
return {
|
|
@@ -4956,6 +5378,9 @@ async function archiveFromDirectory(dirPath, archivePath, options = {}) {
|
|
|
4956
5378
|
let entries = {};
|
|
4957
5379
|
if (kind === "bun") {
|
|
4958
5380
|
const B = globalThis.Bun;
|
|
5381
|
+
if (!B?.Glob || !B.file) {
|
|
5382
|
+
throw new Error("[RuntimeArchiveAdapter] Bun global not available for directory scanning");
|
|
5383
|
+
}
|
|
4959
5384
|
const glob = new B.Glob(options.glob ?? "**/*");
|
|
4960
5385
|
for await (const file of glob.scan(dirPath)) {
|
|
4961
5386
|
const pathMod = await eval('import("node:path")');
|
|
@@ -5569,6 +5994,9 @@ function getPasswordAdapter() {
|
|
|
5569
5994
|
};
|
|
5570
5995
|
return passwordAdapter;
|
|
5571
5996
|
}
|
|
5997
|
+
function resetPasswordAdapter() {
|
|
5998
|
+
passwordAdapter = null;
|
|
5999
|
+
}
|
|
5572
6000
|
async function createSqliteDatabase(path2) {
|
|
5573
6001
|
const kind2 = getRuntimeKind();
|
|
5574
6002
|
const B2 = globalThis.Bun;
|
|
@@ -5670,54 +6098,6 @@ class ConfigManager {
|
|
|
5670
6098
|
}
|
|
5671
6099
|
}
|
|
5672
6100
|
|
|
5673
|
-
// src/exceptions/GravitoException.ts
|
|
5674
|
-
class GravitoException extends Error {
|
|
5675
|
-
status;
|
|
5676
|
-
code;
|
|
5677
|
-
i18nKey;
|
|
5678
|
-
i18nParams;
|
|
5679
|
-
constructor(status, code, options2 = {}) {
|
|
5680
|
-
super(options2.message);
|
|
5681
|
-
this.name = "GravitoException";
|
|
5682
|
-
this.status = status;
|
|
5683
|
-
this.cause = options2.cause;
|
|
5684
|
-
this.code = code;
|
|
5685
|
-
if (options2.i18nKey) {
|
|
5686
|
-
this.i18nKey = options2.i18nKey;
|
|
5687
|
-
}
|
|
5688
|
-
if (options2.i18nParams) {
|
|
5689
|
-
this.i18nParams = options2.i18nParams;
|
|
5690
|
-
}
|
|
5691
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
5692
|
-
}
|
|
5693
|
-
getLocalizedMessage(t) {
|
|
5694
|
-
if (this.i18nKey) {
|
|
5695
|
-
return t(this.i18nKey, this.i18nParams);
|
|
5696
|
-
}
|
|
5697
|
-
return this.message;
|
|
5698
|
-
}
|
|
5699
|
-
}
|
|
5700
|
-
|
|
5701
|
-
// src/exceptions/SystemException.ts
|
|
5702
|
-
class SystemException extends GravitoException {
|
|
5703
|
-
constructor(status, code, options2 = {}) {
|
|
5704
|
-
super(status, code, options2);
|
|
5705
|
-
this.name = "SystemException";
|
|
5706
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
5707
|
-
}
|
|
5708
|
-
}
|
|
5709
|
-
|
|
5710
|
-
// src/exceptions/CircularDependencyException.ts
|
|
5711
|
-
class CircularDependencyException extends SystemException {
|
|
5712
|
-
constructor(key, stack) {
|
|
5713
|
-
const path2 = [...stack, key].map(String).join(" -> ");
|
|
5714
|
-
super(500, "system.circular_dependency", {
|
|
5715
|
-
message: `Circular dependency detected: ${path2}`
|
|
5716
|
-
});
|
|
5717
|
-
this.name = "CircularDependencyException";
|
|
5718
|
-
}
|
|
5719
|
-
}
|
|
5720
|
-
|
|
5721
6101
|
// src/Container.ts
|
|
5722
6102
|
var scopeStorage = new AsyncLocalStorage;
|
|
5723
6103
|
|
|
@@ -5742,6 +6122,17 @@ class Container {
|
|
|
5742
6122
|
scope: "singleton"
|
|
5743
6123
|
});
|
|
5744
6124
|
}
|
|
6125
|
+
singletonInline(namespace, key, factory) {
|
|
6126
|
+
const namespacedKey = `inline:${namespace}:${key}`;
|
|
6127
|
+
if (this.has(namespacedKey)) {
|
|
6128
|
+
if (true) {
|
|
6129
|
+
throw new ContainerBindingCollisionException(`Binding '${namespacedKey}' already registered by plugin '${namespace}'`);
|
|
6130
|
+
}
|
|
6131
|
+
console.warn(`[gravito] Binding '${namespacedKey}' collision detected \u2014 skipping duplicate registration.`);
|
|
6132
|
+
return;
|
|
6133
|
+
}
|
|
6134
|
+
this.singleton(namespacedKey, factory);
|
|
6135
|
+
}
|
|
5745
6136
|
scoped(key, factory) {
|
|
5746
6137
|
this.bindings.set(key, {
|
|
5747
6138
|
factory,
|
|
@@ -5879,46 +6270,6 @@ function detectRequestScopeLeaks(context) {
|
|
|
5879
6270
|
};
|
|
5880
6271
|
}
|
|
5881
6272
|
|
|
5882
|
-
// src/exceptions/HttpException.ts
|
|
5883
|
-
class HttpException extends GravitoException {
|
|
5884
|
-
constructor(status, options2 = {}) {
|
|
5885
|
-
super(status, "HTTP_ERROR", options2);
|
|
5886
|
-
this.name = "HttpException";
|
|
5887
|
-
}
|
|
5888
|
-
}
|
|
5889
|
-
|
|
5890
|
-
// src/exceptions/DomainException.ts
|
|
5891
|
-
class DomainException extends GravitoException {
|
|
5892
|
-
constructor(status, code, options2 = {}) {
|
|
5893
|
-
super(status, code, options2);
|
|
5894
|
-
this.name = "DomainException";
|
|
5895
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
5896
|
-
}
|
|
5897
|
-
}
|
|
5898
|
-
|
|
5899
|
-
// src/exceptions/ValidationException.ts
|
|
5900
|
-
class ValidationException extends DomainException {
|
|
5901
|
-
errors;
|
|
5902
|
-
redirectTo;
|
|
5903
|
-
input;
|
|
5904
|
-
constructor(errors, message = "Validation failed") {
|
|
5905
|
-
super(422, "VALIDATION_ERROR", {
|
|
5906
|
-
message,
|
|
5907
|
-
i18nKey: "errors.validation.failed"
|
|
5908
|
-
});
|
|
5909
|
-
this.name = "ValidationException";
|
|
5910
|
-
this.errors = errors;
|
|
5911
|
-
}
|
|
5912
|
-
withRedirect(url) {
|
|
5913
|
-
this.redirectTo = url;
|
|
5914
|
-
return this;
|
|
5915
|
-
}
|
|
5916
|
-
withInput(input) {
|
|
5917
|
-
this.input = input;
|
|
5918
|
-
return this;
|
|
5919
|
-
}
|
|
5920
|
-
}
|
|
5921
|
-
|
|
5922
6273
|
// src/helpers/response.ts
|
|
5923
6274
|
function ok(data) {
|
|
5924
6275
|
return { success: true, data };
|
|
@@ -9344,59 +9695,60 @@ class EventMetrics {
|
|
|
9344
9695
|
circuitBreakerSuccessesCounter;
|
|
9345
9696
|
circuitBreakerOpenDurationHistogram;
|
|
9346
9697
|
constructor(registry, prefix = "gravito_event_") {
|
|
9347
|
-
|
|
9698
|
+
const reg = registry;
|
|
9699
|
+
this.dispatchLatency = reg.histogram({
|
|
9348
9700
|
name: `${prefix}dispatch_latency_seconds`,
|
|
9349
9701
|
help: "Event dispatch latency in seconds",
|
|
9350
9702
|
labels: ["event_name", "priority"],
|
|
9351
9703
|
buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 2, 5]
|
|
9352
9704
|
});
|
|
9353
|
-
this.listenerExecutionTime =
|
|
9705
|
+
this.listenerExecutionTime = reg.histogram({
|
|
9354
9706
|
name: `${prefix}listener_execution_seconds`,
|
|
9355
9707
|
help: "Listener execution time in seconds",
|
|
9356
9708
|
labels: ["event_name", "listener_index"],
|
|
9357
9709
|
buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 2, 5]
|
|
9358
9710
|
});
|
|
9359
|
-
this.queueDepthGauge =
|
|
9711
|
+
this.queueDepthGauge = reg.gauge({
|
|
9360
9712
|
name: `${prefix}queue_depth`,
|
|
9361
9713
|
help: "Current queue depth by priority",
|
|
9362
9714
|
labels: ["priority"]
|
|
9363
9715
|
});
|
|
9364
|
-
this.failureCounter =
|
|
9716
|
+
this.failureCounter = reg.counter({
|
|
9365
9717
|
name: `${prefix}failures_total`,
|
|
9366
9718
|
help: "Total number of failed event processing",
|
|
9367
9719
|
labels: ["event_name", "error_type"]
|
|
9368
9720
|
});
|
|
9369
|
-
this.timeoutCounter =
|
|
9721
|
+
this.timeoutCounter = reg.counter({
|
|
9370
9722
|
name: `${prefix}timeouts_total`,
|
|
9371
9723
|
help: "Total number of event processing timeouts",
|
|
9372
9724
|
labels: ["event_name"]
|
|
9373
9725
|
});
|
|
9374
|
-
this.processedCounter =
|
|
9726
|
+
this.processedCounter = reg.counter({
|
|
9375
9727
|
name: `${prefix}processed_total`,
|
|
9376
9728
|
help: "Total number of processed events",
|
|
9377
9729
|
labels: ["event_name", "status"]
|
|
9378
9730
|
});
|
|
9379
|
-
this.circuitBreakerStateGauge =
|
|
9731
|
+
this.circuitBreakerStateGauge = reg.gauge({
|
|
9380
9732
|
name: `${prefix}circuit_breaker_state`,
|
|
9381
9733
|
help: "Current circuit breaker state (0=CLOSED, 1=HALF_OPEN, 2=OPEN)",
|
|
9382
9734
|
labels: ["event_name"]
|
|
9383
9735
|
});
|
|
9384
|
-
this.circuitBreakerTransitionsCounter =
|
|
9736
|
+
this.circuitBreakerTransitionsCounter = reg.counter({
|
|
9385
9737
|
name: `${prefix}circuit_breaker_transitions_total`,
|
|
9386
9738
|
help: "Total number of circuit breaker state transitions",
|
|
9387
9739
|
labels: ["event_name", "from_state", "to_state"]
|
|
9388
9740
|
});
|
|
9389
|
-
this.circuitBreakerFailuresCounter =
|
|
9741
|
+
this.circuitBreakerFailuresCounter = reg.counter({
|
|
9390
9742
|
name: `${prefix}circuit_breaker_failures_total`,
|
|
9391
9743
|
help: "Total number of failures tracked by circuit breaker",
|
|
9392
9744
|
labels: ["event_name"]
|
|
9393
9745
|
});
|
|
9394
|
-
this.circuitBreakerSuccessesCounter =
|
|
9746
|
+
this.circuitBreakerSuccessesCounter = reg.counter({
|
|
9395
9747
|
name: `${prefix}circuit_breaker_successes_total`,
|
|
9396
9748
|
help: "Total number of successes tracked by circuit breaker",
|
|
9397
9749
|
labels: ["event_name"]
|
|
9398
9750
|
});
|
|
9399
|
-
this.circuitBreakerOpenDurationHistogram =
|
|
9751
|
+
this.circuitBreakerOpenDurationHistogram = reg.histogram({
|
|
9400
9752
|
name: `${prefix}circuit_breaker_open_duration_seconds`,
|
|
9401
9753
|
help: "Duration of circuit breaker OPEN state in seconds",
|
|
9402
9754
|
labels: ["event_name"],
|
|
@@ -9789,7 +10141,7 @@ class ObservableHookManager extends HookManager {
|
|
|
9789
10141
|
let span;
|
|
9790
10142
|
if (this.eventTracing) {
|
|
9791
10143
|
span = this.eventTracing.startDispatchSpan(hook, callbacks.length, "normal");
|
|
9792
|
-
span
|
|
10144
|
+
span?.setAttributes({ "event.dispatch_mode": "sync" });
|
|
9793
10145
|
} else if (this.eventTracer) {
|
|
9794
10146
|
span = this.eventTracer.startDispatchSpan(hook, callbacks.length, "normal");
|
|
9795
10147
|
}
|
|
@@ -9934,18 +10286,18 @@ class OTelEventMetrics {
|
|
|
9934
10286
|
});
|
|
9935
10287
|
}
|
|
9936
10288
|
});
|
|
9937
|
-
this.cbFailuresCounter = meter2.createCounter
|
|
10289
|
+
this.cbFailuresCounter = meter2.createCounter(`${prefix}circuit_breaker_failures_total`, {
|
|
9938
10290
|
description: "Total number of failures recorded by circuit breakers",
|
|
9939
10291
|
unit: "{failures}"
|
|
9940
|
-
})
|
|
9941
|
-
this.cbSuccessesCounter = meter2.createCounter
|
|
10292
|
+
});
|
|
10293
|
+
this.cbSuccessesCounter = meter2.createCounter(`${prefix}circuit_breaker_successes_total`, {
|
|
9942
10294
|
description: "Total number of successes recorded by circuit breakers",
|
|
9943
10295
|
unit: "{successes}"
|
|
9944
|
-
})
|
|
9945
|
-
this.cbTransitionsCounter = meter2.createCounter
|
|
10296
|
+
});
|
|
10297
|
+
this.cbTransitionsCounter = meter2.createCounter(`${prefix}circuit_breaker_transitions_total`, {
|
|
9946
10298
|
description: "Total number of state transitions in circuit breakers",
|
|
9947
10299
|
unit: "{transitions}"
|
|
9948
|
-
})
|
|
10300
|
+
});
|
|
9949
10301
|
this.cbOpenDurationHistogram = meter2.createHistogram(`${prefix}circuit_breaker_open_duration_seconds`, {
|
|
9950
10302
|
description: "Duration that circuit breakers remain in OPEN state",
|
|
9951
10303
|
unit: "s",
|
|
@@ -9953,10 +10305,10 @@ class OTelEventMetrics {
|
|
|
9953
10305
|
explicitBucketBoundaries: this.cbOpenDurationBuckets
|
|
9954
10306
|
}
|
|
9955
10307
|
});
|
|
9956
|
-
this.backpressureRejectionsCounter = meter2.createCounter
|
|
10308
|
+
this.backpressureRejectionsCounter = meter2.createCounter(`${prefix}backpressure_rejections_total`, {
|
|
9957
10309
|
description: "Total number of events rejected due to backpressure",
|
|
9958
10310
|
unit: "{rejections}"
|
|
9959
|
-
})
|
|
10311
|
+
});
|
|
9960
10312
|
this.backpressureStateGauge = meter2.createObservableGauge(`${prefix}backpressure_state`, {
|
|
9961
10313
|
description: "Current backpressure state (0=NORMAL, 1=WARNING, 2=CRITICAL, 3=OVERFLOW)",
|
|
9962
10314
|
unit: "{state}"
|
|
@@ -9970,14 +10322,14 @@ class OTelEventMetrics {
|
|
|
9970
10322
|
};
|
|
9971
10323
|
observableResult.observe(stateMap[this.backpressureStateValue] ?? 0);
|
|
9972
10324
|
});
|
|
9973
|
-
this.backpressureDegradationsCounter = meter2.createCounter
|
|
10325
|
+
this.backpressureDegradationsCounter = meter2.createCounter(`${prefix}backpressure_degradations_total`, {
|
|
9974
10326
|
description: "Total number of priority degradations due to backpressure",
|
|
9975
10327
|
unit: "{degradations}"
|
|
9976
|
-
})
|
|
9977
|
-
this.dlqEntriesCounter = meter2.createCounter
|
|
10328
|
+
});
|
|
10329
|
+
this.dlqEntriesCounter = meter2.createCounter(`${prefix}dlq_entries_total`, {
|
|
9978
10330
|
description: "Total number of events added to Dead Letter Queue",
|
|
9979
10331
|
unit: "{entries}"
|
|
9980
|
-
})
|
|
10332
|
+
});
|
|
9981
10333
|
this.dlqDepthGauge = meter2.createObservableGauge(`${prefix}dlq_depth`, {
|
|
9982
10334
|
description: "Current Dead Letter Queue depth",
|
|
9983
10335
|
unit: "{events}"
|
|
@@ -9987,18 +10339,18 @@ class OTelEventMetrics {
|
|
|
9987
10339
|
observableResult.observe(this.dlqDepthCallback());
|
|
9988
10340
|
}
|
|
9989
10341
|
});
|
|
9990
|
-
this.dlqRequeueCounter = meter2.createCounter
|
|
10342
|
+
this.dlqRequeueCounter = meter2.createCounter(`${prefix}dlq_requeue_total`, {
|
|
9991
10343
|
description: "Total number of DLQ requeue attempts",
|
|
9992
10344
|
unit: "{attempts}"
|
|
9993
|
-
})
|
|
9994
|
-
this.retryAttemptsCounter = meter2.createCounter
|
|
10345
|
+
});
|
|
10346
|
+
this.retryAttemptsCounter = meter2.createCounter(`${prefix}retry_attempts_total`, {
|
|
9995
10347
|
description: "Total number of event retry attempts",
|
|
9996
10348
|
unit: "{attempts}"
|
|
9997
|
-
})
|
|
9998
|
-
this.priorityEscalationCounter = meter2.createCounter
|
|
10349
|
+
});
|
|
10350
|
+
this.priorityEscalationCounter = meter2.createCounter(`${prefix}priority_escalation_total`, {
|
|
9999
10351
|
description: "Total number of priority escalations",
|
|
10000
10352
|
unit: "{escalations}"
|
|
10001
|
-
})
|
|
10353
|
+
});
|
|
10002
10354
|
}
|
|
10003
10355
|
recordDispatchDuration(eventName, priority, durationSeconds) {
|
|
10004
10356
|
this.dispatchDurationHistogram.record(durationSeconds, {
|
|
@@ -10933,24 +11285,6 @@ class CookieJar {
|
|
|
10933
11285
|
}
|
|
10934
11286
|
}
|
|
10935
11287
|
|
|
10936
|
-
// src/exceptions/ModelNotFoundException.ts
|
|
10937
|
-
class ModelNotFoundException extends GravitoException {
|
|
10938
|
-
model;
|
|
10939
|
-
id;
|
|
10940
|
-
constructor(model, id) {
|
|
10941
|
-
super(404, "NOT_FOUND", {
|
|
10942
|
-
message: `${model} not found.`,
|
|
10943
|
-
i18nKey: "errors.model.not_found",
|
|
10944
|
-
i18nParams: { model, id: String(id ?? "") }
|
|
10945
|
-
});
|
|
10946
|
-
this.name = "ModelNotFoundException";
|
|
10947
|
-
this.model = model;
|
|
10948
|
-
if (id !== undefined) {
|
|
10949
|
-
this.id = id;
|
|
10950
|
-
}
|
|
10951
|
-
}
|
|
10952
|
-
}
|
|
10953
|
-
|
|
10954
11288
|
// src/Route.ts
|
|
10955
11289
|
class Route {
|
|
10956
11290
|
router;
|
|
@@ -10967,6 +11301,13 @@ class Route {
|
|
|
10967
11301
|
this.router.registerName(name, this.method, this.path, this.options);
|
|
10968
11302
|
return this;
|
|
10969
11303
|
}
|
|
11304
|
+
schema(schemas) {
|
|
11305
|
+
this.options.schema = {
|
|
11306
|
+
...this.options.schema || {},
|
|
11307
|
+
...schemas
|
|
11308
|
+
};
|
|
11309
|
+
return this;
|
|
11310
|
+
}
|
|
10970
11311
|
static get(path2, requestOrHandlerOrMiddleware, handler) {
|
|
10971
11312
|
return router().req("get", path2, requestOrHandlerOrMiddleware, handler);
|
|
10972
11313
|
}
|
|
@@ -11162,18 +11503,20 @@ class Router {
|
|
|
11162
11503
|
const compiled = [];
|
|
11163
11504
|
const nameMap = new Map;
|
|
11164
11505
|
for (const [name, info] of this.namedRoutes) {
|
|
11165
|
-
nameMap.set(`${info.method.toUpperCase()}:${info.path}`, name);
|
|
11506
|
+
nameMap.set(`${info.method.toUpperCase()}:${info.path}`, { name, options: info.options });
|
|
11166
11507
|
}
|
|
11167
11508
|
const compiledKeys = new Set;
|
|
11168
11509
|
for (const route of this.routes) {
|
|
11169
11510
|
const method = route.method.toUpperCase();
|
|
11170
11511
|
const key = `${method}:${route.path}`;
|
|
11171
11512
|
compiledKeys.add(key);
|
|
11513
|
+
const namedInfo = nameMap.get(key);
|
|
11172
11514
|
compiled.push({
|
|
11173
11515
|
method,
|
|
11174
11516
|
path: route.path,
|
|
11175
11517
|
domain: route.domain,
|
|
11176
|
-
name:
|
|
11518
|
+
name: namedInfo?.name,
|
|
11519
|
+
schema: route.options?.schema || namedInfo?.options?.schema
|
|
11177
11520
|
});
|
|
11178
11521
|
}
|
|
11179
11522
|
for (const [name, info] of this.namedRoutes) {
|
|
@@ -11183,7 +11526,8 @@ class Router {
|
|
|
11183
11526
|
name,
|
|
11184
11527
|
method: info.method.toUpperCase(),
|
|
11185
11528
|
path: info.path,
|
|
11186
|
-
domain: info.domain
|
|
11529
|
+
domain: info.domain,
|
|
11530
|
+
schema: info.options?.schema
|
|
11187
11531
|
});
|
|
11188
11532
|
}
|
|
11189
11533
|
}
|
|
@@ -11194,7 +11538,8 @@ class Router {
|
|
|
11194
11538
|
this.namedRoutes.set(name, {
|
|
11195
11539
|
method: method.toUpperCase(),
|
|
11196
11540
|
path: fullPath,
|
|
11197
|
-
domain: options2.domain
|
|
11541
|
+
domain: options2.domain,
|
|
11542
|
+
options: options2
|
|
11198
11543
|
});
|
|
11199
11544
|
}
|
|
11200
11545
|
url(name, params = {}, query = {}) {
|
|
@@ -11234,7 +11579,7 @@ class Router {
|
|
|
11234
11579
|
if (modelClass && typeof modelClass === "object" && "find" in modelClass && typeof modelClass.find === "function") {
|
|
11235
11580
|
const instance = await modelClass.find(id);
|
|
11236
11581
|
if (!instance) {
|
|
11237
|
-
throw new
|
|
11582
|
+
throw new ModelNotFoundException(param, String(id));
|
|
11238
11583
|
}
|
|
11239
11584
|
return instance;
|
|
11240
11585
|
}
|
|
@@ -11256,17 +11601,9 @@ class Router {
|
|
|
11256
11601
|
if (!resolver) {
|
|
11257
11602
|
continue;
|
|
11258
11603
|
}
|
|
11259
|
-
|
|
11260
|
-
|
|
11261
|
-
|
|
11262
|
-
hasResolvedModels = true;
|
|
11263
|
-
} catch (err) {
|
|
11264
|
-
const message = err instanceof Error ? err.message : undefined;
|
|
11265
|
-
if (message === "ModelNotFound") {
|
|
11266
|
-
throw new ModelNotFoundException(param, value2);
|
|
11267
|
-
}
|
|
11268
|
-
throw err;
|
|
11269
|
-
}
|
|
11604
|
+
const resolved = await resolver(value2);
|
|
11605
|
+
routeModels[param] = resolved;
|
|
11606
|
+
hasResolvedModels = true;
|
|
11270
11607
|
}
|
|
11271
11608
|
if (hasResolvedModels) {
|
|
11272
11609
|
c.set("routeModels", routeModels);
|
|
@@ -11330,7 +11667,6 @@ class Router {
|
|
|
11330
11667
|
}
|
|
11331
11668
|
req(method, path2, requestOrHandlerOrMiddleware, handler, options2 = {}) {
|
|
11332
11669
|
const fullPath = (options2.prefix || "") + path2;
|
|
11333
|
-
console.log(`[Router] Registering ${method.toUpperCase()} ${fullPath}`);
|
|
11334
11670
|
let formRequestMiddleware = null;
|
|
11335
11671
|
let routeMiddleware = [];
|
|
11336
11672
|
let finalRouteHandler;
|
|
@@ -11372,11 +11708,16 @@ class Router {
|
|
|
11372
11708
|
if (c.req.header("host") !== options2.domain) {
|
|
11373
11709
|
return c.text("Not Found", 404);
|
|
11374
11710
|
}
|
|
11375
|
-
await next();
|
|
11711
|
+
return await next();
|
|
11376
11712
|
};
|
|
11377
11713
|
handlers.unshift(domainCheck);
|
|
11378
11714
|
}
|
|
11379
|
-
this.routes.push({
|
|
11715
|
+
this.routes.push({
|
|
11716
|
+
method: method.toUpperCase(),
|
|
11717
|
+
path: fullPath,
|
|
11718
|
+
domain: options2.domain,
|
|
11719
|
+
options: options2
|
|
11720
|
+
});
|
|
11380
11721
|
this.core.adapter.route(method, fullPath, ...handlers);
|
|
11381
11722
|
return new Route(this, method, fullPath, options2);
|
|
11382
11723
|
}
|
|
@@ -11494,6 +11835,7 @@ class PlanetCore {
|
|
|
11494
11835
|
services = new Map;
|
|
11495
11836
|
encrypter;
|
|
11496
11837
|
hasher;
|
|
11838
|
+
installedOrbits = [];
|
|
11497
11839
|
observabilityProvider;
|
|
11498
11840
|
providers = [];
|
|
11499
11841
|
deferredProviders = new Map;
|
|
@@ -11502,7 +11844,7 @@ class PlanetCore {
|
|
|
11502
11844
|
static GLOBAL_SHUTDOWN_TIMEOUT = 1e4;
|
|
11503
11845
|
async initializeObservabilityAsync(obsConfig) {
|
|
11504
11846
|
try {
|
|
11505
|
-
if (this.observabilityProvider && this.observabilityProvider !==
|
|
11847
|
+
if (this.observabilityProvider && this.observabilityProvider._isNoOp !== true) {
|
|
11506
11848
|
this.logger.info("[Observability] \u2705 Using observability provider from @gravito/monitor");
|
|
11507
11849
|
if (obsConfig?.prometheus?.enabled !== false) {
|
|
11508
11850
|
await this.initializePrometheusAsync(obsConfig);
|
|
@@ -11544,10 +11886,11 @@ class PlanetCore {
|
|
|
11544
11886
|
this.logger.debug("[Observability] Prometheus setup moved to @gravito/monitor. Use monitor package for metrics initialization.");
|
|
11545
11887
|
}
|
|
11546
11888
|
register(provider) {
|
|
11547
|
-
|
|
11548
|
-
|
|
11889
|
+
const providerRecord = provider;
|
|
11890
|
+
if (typeof providerRecord["setCore"] === "function") {
|
|
11891
|
+
providerRecord["setCore"](this);
|
|
11549
11892
|
} else {
|
|
11550
|
-
|
|
11893
|
+
providerRecord["core"] = this;
|
|
11551
11894
|
}
|
|
11552
11895
|
if (provider.deferred) {
|
|
11553
11896
|
const services = provider.provides();
|
|
@@ -11718,8 +12061,38 @@ class PlanetCore {
|
|
|
11718
12061
|
process.on("SIGTERM", () => handleSignal("SIGTERM"));
|
|
11719
12062
|
process.on("SIGINT", () => handleSignal("SIGINT"));
|
|
11720
12063
|
}
|
|
12064
|
+
async plugin(config3) {
|
|
12065
|
+
if (!config3.name) {
|
|
12066
|
+
throw new Error('plugin(): Lite Satellites require a "name" property to enable safe service namespacing. Consider naming it based on the feature (e.g., "ping", "health-check").');
|
|
12067
|
+
}
|
|
12068
|
+
const alreadyRegistered = this.installedOrbits.some((orbit) => orbit.name === config3.name);
|
|
12069
|
+
if (alreadyRegistered) {
|
|
12070
|
+
if (true) {
|
|
12071
|
+
throw new ContainerBindingCollisionException(`Lite Satellite name '${config3.name}' already registered`);
|
|
12072
|
+
}
|
|
12073
|
+
this.logger.warn(`[gravito] Lite Satellite '${config3.name}' already registered \u2014 skipping duplicate installation.`);
|
|
12074
|
+
return this;
|
|
12075
|
+
}
|
|
12076
|
+
this.logger.debug(`\uD83D\uDD0C Installing Lite Satellite: ${config3.name}`);
|
|
12077
|
+
this.installedOrbits.push({
|
|
12078
|
+
name: config3.name,
|
|
12079
|
+
dependencies: config3.dependencies || []
|
|
12080
|
+
});
|
|
12081
|
+
await config3.install(this);
|
|
12082
|
+
return this;
|
|
12083
|
+
}
|
|
11721
12084
|
async orbit(orbit) {
|
|
11722
12085
|
const instance = typeof orbit === "function" ? new orbit : orbit;
|
|
12086
|
+
const name = instance.name || instance.constructor.name;
|
|
12087
|
+
if (instance.name) {
|
|
12088
|
+
this.logger.debug(`\uD83D\uDEF0\uFE0F Installing Orbit: ${instance.name}`);
|
|
12089
|
+
} else {
|
|
12090
|
+
this.logger.debug(`\uD83D\uDEF0\uFE0F Installing Orbit: ${instance.constructor.name}`);
|
|
12091
|
+
}
|
|
12092
|
+
this.installedOrbits.push({
|
|
12093
|
+
name,
|
|
12094
|
+
dependencies: instance.dependencies || []
|
|
12095
|
+
});
|
|
11723
12096
|
await instance.install(this);
|
|
11724
12097
|
return this;
|
|
11725
12098
|
}
|
|
@@ -11744,17 +12117,24 @@ class PlanetCore {
|
|
|
11744
12117
|
...config3.logger && { logger: config3.logger },
|
|
11745
12118
|
...config3.config && { config: config3.config },
|
|
11746
12119
|
...config3.adapter && { adapter: config3.adapter },
|
|
11747
|
-
...config3.container && { container: config3.container }
|
|
12120
|
+
...config3.container && { container: config3.container },
|
|
12121
|
+
...config3.observabilityProvider && { observabilityProvider: config3.observabilityProvider }
|
|
11748
12122
|
});
|
|
12123
|
+
const features = NativeOrbitDetector.detectBunCapabilities();
|
|
12124
|
+
core.logger.info(formatCapabilityReport(features));
|
|
11749
12125
|
if (config3.orbits) {
|
|
11750
12126
|
for (const OrbitClassOrInstance of config3.orbits) {
|
|
11751
|
-
|
|
11752
|
-
|
|
11753
|
-
orbit = new OrbitClassOrInstance;
|
|
12127
|
+
if (typeof OrbitClassOrInstance !== "function" && OrbitClassOrInstance.name) {
|
|
12128
|
+
await core.plugin(OrbitClassOrInstance);
|
|
11754
12129
|
} else {
|
|
11755
|
-
orbit
|
|
12130
|
+
let orbit;
|
|
12131
|
+
if (typeof OrbitClassOrInstance === "function") {
|
|
12132
|
+
orbit = new OrbitClassOrInstance;
|
|
12133
|
+
} else {
|
|
12134
|
+
orbit = OrbitClassOrInstance;
|
|
12135
|
+
}
|
|
12136
|
+
await orbit.install(core);
|
|
11756
12137
|
}
|
|
11757
|
-
await orbit.install(core);
|
|
11758
12138
|
}
|
|
11759
12139
|
}
|
|
11760
12140
|
return core;
|
|
@@ -12524,7 +12904,8 @@ class MessageQueueBridge {
|
|
|
12524
12904
|
throw new Error(`[MessageQueueBridge] No listeners registered for event: ${eventName}`);
|
|
12525
12905
|
}
|
|
12526
12906
|
if (this.config.enableCircuitBreaker) {
|
|
12527
|
-
const
|
|
12907
|
+
const hm = this.config.hookManager;
|
|
12908
|
+
const breaker = hm.getCircuitBreaker?.(eventName);
|
|
12528
12909
|
if (breaker?.getState?.() === "OPEN") {
|
|
12529
12910
|
throw new Error(`[MessageQueueBridge] Circuit breaker is OPEN for event: ${eventName}`);
|
|
12530
12911
|
}
|
|
@@ -12650,9 +13031,9 @@ class RetryScheduler {
|
|
|
12650
13031
|
try {
|
|
12651
13032
|
const queue = this.getOrCreateQueue(eventName);
|
|
12652
13033
|
const delay = this.calculateDelay(retryCount);
|
|
12653
|
-
const
|
|
12654
|
-
if (typeof
|
|
12655
|
-
await
|
|
13034
|
+
const queueObj = queue;
|
|
13035
|
+
if (typeof queueObj.add === "function") {
|
|
13036
|
+
await queueObj.add.call(queue, "retry", { payload, error: error.message, retryCount }, { delay });
|
|
12656
13037
|
}
|
|
12657
13038
|
} catch (schedulerError) {
|
|
12658
13039
|
const err = schedulerError instanceof Error ? schedulerError : new Error(String(schedulerError));
|
|
@@ -13221,101 +13602,6 @@ class QueueDashboard {
|
|
|
13221
13602
|
return value2.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\n");
|
|
13222
13603
|
}
|
|
13223
13604
|
}
|
|
13224
|
-
// src/exceptions/AuthenticationException.ts
|
|
13225
|
-
class AuthenticationException extends DomainException {
|
|
13226
|
-
constructor(message = "Unauthenticated.") {
|
|
13227
|
-
super(401, "UNAUTHENTICATED", {
|
|
13228
|
-
message,
|
|
13229
|
-
i18nKey: "errors.authentication.unauthenticated"
|
|
13230
|
-
});
|
|
13231
|
-
this.name = "AuthenticationException";
|
|
13232
|
-
}
|
|
13233
|
-
}
|
|
13234
|
-
|
|
13235
|
-
// src/exceptions/AuthException.ts
|
|
13236
|
-
class AuthException extends DomainException {
|
|
13237
|
-
constructor(status, code, options2 = {}) {
|
|
13238
|
-
super(status, code, options2);
|
|
13239
|
-
this.name = "AuthException";
|
|
13240
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
13241
|
-
}
|
|
13242
|
-
}
|
|
13243
|
-
|
|
13244
|
-
// src/exceptions/AuthorizationException.ts
|
|
13245
|
-
class AuthorizationException extends DomainException {
|
|
13246
|
-
constructor(message = "This action is unauthorized.") {
|
|
13247
|
-
super(403, "FORBIDDEN", {
|
|
13248
|
-
message,
|
|
13249
|
-
i18nKey: "errors.authorization.forbidden"
|
|
13250
|
-
});
|
|
13251
|
-
this.name = "AuthorizationException";
|
|
13252
|
-
}
|
|
13253
|
-
}
|
|
13254
|
-
|
|
13255
|
-
// src/exceptions/InfrastructureException.ts
|
|
13256
|
-
class InfrastructureException extends GravitoException {
|
|
13257
|
-
retryable;
|
|
13258
|
-
constructor(status, code, options2 = {}) {
|
|
13259
|
-
super(status, code, options2);
|
|
13260
|
-
this.name = "InfrastructureException";
|
|
13261
|
-
this.retryable = options2.retryable ?? false;
|
|
13262
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
13263
|
-
}
|
|
13264
|
-
}
|
|
13265
|
-
|
|
13266
|
-
// src/exceptions/CacheException.ts
|
|
13267
|
-
class CacheException extends InfrastructureException {
|
|
13268
|
-
constructor(status, code, options2 = {}) {
|
|
13269
|
-
super(status, code, options2);
|
|
13270
|
-
this.name = "CacheException";
|
|
13271
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
13272
|
-
}
|
|
13273
|
-
}
|
|
13274
|
-
|
|
13275
|
-
// src/exceptions/ConfigurationException.ts
|
|
13276
|
-
class ConfigurationException extends SystemException {
|
|
13277
|
-
constructor(message, options2 = {}) {
|
|
13278
|
-
super(500, "system.configuration_error", { ...options2, message });
|
|
13279
|
-
this.name = "ConfigurationException";
|
|
13280
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
13281
|
-
}
|
|
13282
|
-
}
|
|
13283
|
-
|
|
13284
|
-
// src/exceptions/DatabaseException.ts
|
|
13285
|
-
class DatabaseException extends InfrastructureException {
|
|
13286
|
-
constructor(status, code, options2 = {}) {
|
|
13287
|
-
super(status, code, options2);
|
|
13288
|
-
this.name = "DatabaseException";
|
|
13289
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
13290
|
-
}
|
|
13291
|
-
}
|
|
13292
|
-
|
|
13293
|
-
// src/exceptions/QueueException.ts
|
|
13294
|
-
class QueueException extends InfrastructureException {
|
|
13295
|
-
constructor(status, code, options2 = {}) {
|
|
13296
|
-
super(status, code, options2);
|
|
13297
|
-
this.name = "QueueException";
|
|
13298
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
13299
|
-
}
|
|
13300
|
-
}
|
|
13301
|
-
|
|
13302
|
-
// src/exceptions/StorageException.ts
|
|
13303
|
-
class StorageException extends InfrastructureException {
|
|
13304
|
-
constructor(status, code, options2 = {}) {
|
|
13305
|
-
super(status, code, options2);
|
|
13306
|
-
this.name = "StorageException";
|
|
13307
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
13308
|
-
}
|
|
13309
|
-
}
|
|
13310
|
-
|
|
13311
|
-
// src/exceptions/StreamException.ts
|
|
13312
|
-
class StreamException extends InfrastructureException {
|
|
13313
|
-
constructor(status, code, options2 = {}) {
|
|
13314
|
-
super(status, code, options2);
|
|
13315
|
-
this.name = "StreamException";
|
|
13316
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
13317
|
-
}
|
|
13318
|
-
}
|
|
13319
13605
|
// src/ServiceProvider.ts
|
|
13320
13606
|
class ServiceProvider {
|
|
13321
13607
|
core;
|
|
@@ -13539,15 +13825,19 @@ class TestResponse {
|
|
|
13539
13825
|
async assertJsonStructure(structure) {
|
|
13540
13826
|
const json = await this.getJson();
|
|
13541
13827
|
const checkKeys = (data2, struct) => {
|
|
13542
|
-
|
|
13543
|
-
|
|
13544
|
-
|
|
13545
|
-
|
|
13546
|
-
|
|
13828
|
+
const structObj = struct;
|
|
13829
|
+
const dataObj = data2;
|
|
13830
|
+
for (const key in structObj) {
|
|
13831
|
+
if (Array.isArray(structObj[key])) {
|
|
13832
|
+
expect(Array.isArray(dataObj[key])).toBe(true);
|
|
13833
|
+
const dataArr = dataObj[key];
|
|
13834
|
+
const structArr = structObj[key];
|
|
13835
|
+
if (dataArr.length > 0) {
|
|
13836
|
+
checkKeys(dataArr[0], structArr[0]);
|
|
13547
13837
|
}
|
|
13548
|
-
} else if (typeof
|
|
13549
|
-
expect(typeof
|
|
13550
|
-
checkKeys(
|
|
13838
|
+
} else if (typeof structObj[key] === "object") {
|
|
13839
|
+
expect(typeof dataObj[key]).toBe("object");
|
|
13840
|
+
checkKeys(dataObj[key], structObj[key]);
|
|
13551
13841
|
} else {
|
|
13552
13842
|
expect(data2).toHaveProperty(key);
|
|
13553
13843
|
}
|
|
@@ -13996,6 +14286,7 @@ export {
|
|
|
13996
14286
|
runtimeAppendFile,
|
|
13997
14287
|
router,
|
|
13998
14288
|
resetRuntimeAdapter,
|
|
14289
|
+
resetPasswordAdapter,
|
|
13999
14290
|
registerQueueCommands,
|
|
14000
14291
|
registerGlobalErrorHandlers,
|
|
14001
14292
|
old,
|
|
@@ -14020,6 +14311,7 @@ export {
|
|
|
14020
14311
|
getCookie,
|
|
14021
14312
|
getCompressionAdapter,
|
|
14022
14313
|
getArchiveAdapter,
|
|
14314
|
+
formatCapabilityReport,
|
|
14023
14315
|
filled,
|
|
14024
14316
|
fail,
|
|
14025
14317
|
extractRequestScopeErrorContext,
|
|
@@ -14081,6 +14373,7 @@ export {
|
|
|
14081
14373
|
ObservableHookManager,
|
|
14082
14374
|
OTelEventMetrics,
|
|
14083
14375
|
NodeType,
|
|
14376
|
+
NativeOrbitDetector,
|
|
14084
14377
|
ModelNotFoundException,
|
|
14085
14378
|
InfrastructureException,
|
|
14086
14379
|
IdempotencyCache,
|
|
@@ -14131,4 +14424,4 @@ export {
|
|
|
14131
14424
|
Application
|
|
14132
14425
|
};
|
|
14133
14426
|
|
|
14134
|
-
//# debugId=
|
|
14427
|
+
//# debugId=AFB01087B997521264756E2164756E21
|