threadforge 0.1.1 → 0.2.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 +52 -20
- package/bin/forge.js +2 -1058
- package/bin/host-commands.d.ts +2 -0
- package/bin/host-commands.d.ts.map +1 -0
- package/bin/host-commands.js +7 -8
- package/bin/platform-commands.d.ts +2 -0
- package/bin/platform-commands.d.ts.map +1 -0
- package/bin/platform-commands.js +118 -36
- package/dist/cli/base-command.d.ts +12 -0
- package/dist/cli/base-command.d.ts.map +1 -0
- package/dist/cli/base-command.js +25 -0
- package/dist/cli/base-command.js.map +1 -0
- package/dist/cli/commands/build.d.ts +10 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +110 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/deploy.d.ts +12 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -0
- package/dist/cli/commands/deploy.js +143 -0
- package/dist/cli/commands/deploy.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +10 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +138 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +10 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +76 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/host.d.ts +8 -0
- package/dist/cli/commands/host.d.ts.map +1 -0
- package/dist/cli/commands/host.js +20 -0
- package/dist/cli/commands/host.js.map +1 -0
- package/dist/cli/commands/init.d.ts +16 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +246 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/platform.d.ts +8 -0
- package/dist/cli/commands/platform.d.ts.map +1 -0
- package/dist/cli/commands/platform.js +20 -0
- package/dist/cli/commands/platform.js.map +1 -0
- package/dist/cli/commands/restart.d.ts +8 -0
- package/dist/cli/commands/restart.d.ts.map +1 -0
- package/dist/cli/commands/restart.js +13 -0
- package/dist/cli/commands/restart.js.map +1 -0
- package/dist/cli/commands/scaffold/frontend.d.ts +10 -0
- package/dist/cli/commands/scaffold/frontend.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/frontend.js +130 -0
- package/dist/cli/commands/scaffold/frontend.js.map +1 -0
- package/dist/cli/commands/scaffold/react.d.ts +7 -0
- package/dist/cli/commands/scaffold/react.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/react.js +12 -0
- package/dist/cli/commands/scaffold/react.js.map +1 -0
- package/dist/cli/commands/scale.d.ts +8 -0
- package/dist/cli/commands/scale.d.ts.map +1 -0
- package/dist/cli/commands/scale.js +13 -0
- package/dist/cli/commands/scale.js.map +1 -0
- package/dist/cli/commands/start.d.ts +10 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +71 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +11 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +60 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +10 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +89 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/util/config-discovery.d.ts +8 -0
- package/dist/cli/util/config-discovery.d.ts.map +1 -0
- package/dist/cli/util/config-discovery.js +70 -0
- package/dist/cli/util/config-discovery.js.map +1 -0
- package/dist/cli/util/config-patcher.d.ts +17 -0
- package/dist/cli/util/config-patcher.d.ts.map +1 -0
- package/dist/cli/util/config-patcher.js +439 -0
- package/dist/cli/util/config-patcher.js.map +1 -0
- package/dist/cli/util/frontend-dev.d.ts +8 -0
- package/dist/cli/util/frontend-dev.d.ts.map +1 -0
- package/dist/cli/util/frontend-dev.js +117 -0
- package/dist/cli/util/frontend-dev.js.map +1 -0
- package/dist/cli/util/process.d.ts +5 -0
- package/dist/cli/util/process.d.ts.map +1 -0
- package/dist/cli/util/process.js +17 -0
- package/dist/cli/util/process.js.map +1 -0
- package/dist/cli/util/templates.d.ts +10 -0
- package/dist/cli/util/templates.d.ts.map +1 -0
- package/dist/cli/util/templates.js +157 -0
- package/dist/cli/util/templates.js.map +1 -0
- package/dist/core/AlertSink.d.ts +83 -0
- package/dist/core/AlertSink.d.ts.map +1 -0
- package/dist/core/AlertSink.js +126 -0
- package/dist/core/AlertSink.js.map +1 -0
- package/dist/core/DirectMessageBus.d.ts +88 -0
- package/dist/core/DirectMessageBus.d.ts.map +1 -0
- package/dist/core/DirectMessageBus.js +352 -0
- package/dist/core/DirectMessageBus.js.map +1 -0
- package/dist/core/EndpointResolver.d.ts +111 -0
- package/dist/core/EndpointResolver.d.ts.map +1 -0
- package/dist/core/EndpointResolver.js +336 -0
- package/dist/core/EndpointResolver.js.map +1 -0
- package/dist/core/ForgeContext.d.ts +221 -0
- package/dist/core/ForgeContext.d.ts.map +1 -0
- package/dist/core/ForgeContext.js +1169 -0
- package/dist/core/ForgeContext.js.map +1 -0
- package/dist/core/ForgeEndpoints.d.ts +71 -0
- package/dist/core/ForgeEndpoints.d.ts.map +1 -0
- package/dist/core/ForgeEndpoints.js +442 -0
- package/dist/core/ForgeEndpoints.js.map +1 -0
- package/dist/core/ForgeHost.d.ts +82 -0
- package/dist/core/ForgeHost.d.ts.map +1 -0
- package/dist/core/ForgeHost.js +107 -0
- package/dist/core/ForgeHost.js.map +1 -0
- package/dist/core/ForgePlatform.d.ts +96 -0
- package/dist/core/ForgePlatform.d.ts.map +1 -0
- package/dist/core/ForgePlatform.js +136 -0
- package/dist/core/ForgePlatform.js.map +1 -0
- package/dist/core/ForgeWebSocket.d.ts +56 -0
- package/dist/core/ForgeWebSocket.d.ts.map +1 -0
- package/dist/core/ForgeWebSocket.js +415 -0
- package/dist/core/ForgeWebSocket.js.map +1 -0
- package/dist/core/Ingress.d.ts +329 -0
- package/dist/core/Ingress.d.ts.map +1 -0
- package/dist/core/Ingress.js +694 -0
- package/dist/core/Ingress.js.map +1 -0
- package/dist/core/Interceptors.d.ts +134 -0
- package/dist/core/Interceptors.d.ts.map +1 -0
- package/dist/core/Interceptors.js +416 -0
- package/dist/core/Interceptors.js.map +1 -0
- package/dist/core/Logger.d.ts +20 -0
- package/dist/core/Logger.d.ts.map +1 -0
- package/dist/core/Logger.js +77 -0
- package/dist/core/Logger.js.map +1 -0
- package/dist/core/MessageBus.d.ts +15 -0
- package/dist/core/MessageBus.d.ts.map +1 -0
- package/dist/core/MessageBus.js +18 -0
- package/dist/core/MessageBus.js.map +1 -0
- package/dist/core/Prometheus.d.ts +80 -0
- package/dist/core/Prometheus.d.ts.map +1 -0
- package/dist/core/Prometheus.js +332 -0
- package/dist/core/Prometheus.js.map +1 -0
- package/dist/core/RequestContext.d.ts +214 -0
- package/dist/core/RequestContext.d.ts.map +1 -0
- package/dist/core/RequestContext.js +556 -0
- package/dist/core/RequestContext.js.map +1 -0
- package/dist/core/Router.d.ts +45 -0
- package/dist/core/Router.d.ts.map +1 -0
- package/dist/core/Router.js +285 -0
- package/dist/core/Router.js.map +1 -0
- package/dist/core/RoutingStrategy.d.ts +116 -0
- package/dist/core/RoutingStrategy.d.ts.map +1 -0
- package/dist/core/RoutingStrategy.js +306 -0
- package/dist/core/RoutingStrategy.js.map +1 -0
- package/dist/core/RpcConfig.d.ts +72 -0
- package/dist/core/RpcConfig.d.ts.map +1 -0
- package/dist/core/RpcConfig.js +127 -0
- package/dist/core/RpcConfig.js.map +1 -0
- package/dist/core/SignatureCache.d.ts +81 -0
- package/dist/core/SignatureCache.d.ts.map +1 -0
- package/dist/core/SignatureCache.js +172 -0
- package/dist/core/SignatureCache.js.map +1 -0
- package/dist/core/StaticFileServer.d.ts +34 -0
- package/dist/core/StaticFileServer.d.ts.map +1 -0
- package/dist/core/StaticFileServer.js +497 -0
- package/dist/core/StaticFileServer.js.map +1 -0
- package/dist/core/Supervisor.d.ts +198 -0
- package/dist/core/Supervisor.d.ts.map +1 -0
- package/dist/core/Supervisor.js +1418 -0
- package/dist/core/Supervisor.js.map +1 -0
- package/dist/core/ThreadAllocator.d.ts +52 -0
- package/dist/core/ThreadAllocator.d.ts.map +1 -0
- package/dist/core/ThreadAllocator.js +174 -0
- package/dist/core/ThreadAllocator.js.map +1 -0
- package/dist/core/WorkerChannelManager.d.ts +130 -0
- package/dist/core/WorkerChannelManager.d.ts.map +1 -0
- package/dist/core/WorkerChannelManager.js +956 -0
- package/dist/core/WorkerChannelManager.js.map +1 -0
- package/dist/core/config-enums.d.ts +41 -0
- package/dist/core/config-enums.d.ts.map +1 -0
- package/dist/core/config-enums.js +59 -0
- package/dist/core/config-enums.js.map +1 -0
- package/dist/core/config.d.ts +159 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +694 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/host-config.d.ts +146 -0
- package/dist/core/host-config.d.ts.map +1 -0
- package/dist/core/host-config.js +312 -0
- package/dist/core/host-config.js.map +1 -0
- package/dist/core/ipc-errors.d.ts +27 -0
- package/dist/core/ipc-errors.d.ts.map +1 -0
- package/dist/core/ipc-errors.js +36 -0
- package/dist/core/ipc-errors.js.map +1 -0
- package/dist/core/network-utils.d.ts +35 -0
- package/dist/core/network-utils.d.ts.map +1 -0
- package/dist/core/network-utils.js +145 -0
- package/dist/core/network-utils.js.map +1 -0
- package/dist/core/platform-config.d.ts +142 -0
- package/dist/core/platform-config.d.ts.map +1 -0
- package/dist/core/platform-config.js +299 -0
- package/dist/core/platform-config.js.map +1 -0
- package/dist/decorators/ServiceProxy.d.ts +175 -0
- package/dist/decorators/ServiceProxy.d.ts.map +1 -0
- package/dist/decorators/ServiceProxy.js +969 -0
- package/dist/decorators/ServiceProxy.js.map +1 -0
- package/dist/decorators/index.d.ts +146 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +545 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/deploy/NginxGenerator.d.ts +165 -0
- package/dist/deploy/NginxGenerator.d.ts.map +1 -0
- package/dist/deploy/NginxGenerator.js +781 -0
- package/dist/deploy/NginxGenerator.js.map +1 -0
- package/dist/deploy/PlatformManifestGenerator.d.ts +43 -0
- package/dist/deploy/PlatformManifestGenerator.d.ts.map +1 -0
- package/dist/deploy/PlatformManifestGenerator.js +80 -0
- package/dist/deploy/PlatformManifestGenerator.js.map +1 -0
- package/dist/deploy/RouteManifestGenerator.d.ts +42 -0
- package/dist/deploy/RouteManifestGenerator.d.ts.map +1 -0
- package/dist/deploy/RouteManifestGenerator.js +105 -0
- package/dist/deploy/RouteManifestGenerator.js.map +1 -0
- package/dist/deploy/index.d.ts +210 -0
- package/dist/deploy/index.d.ts.map +1 -0
- package/dist/deploy/index.js +918 -0
- package/dist/deploy/index.js.map +1 -0
- package/dist/frontend/FrontendDevLifecycle.d.ts +26 -0
- package/dist/frontend/FrontendDevLifecycle.d.ts.map +1 -0
- package/dist/frontend/FrontendDevLifecycle.js +60 -0
- package/dist/frontend/FrontendDevLifecycle.js.map +1 -0
- package/dist/frontend/FrontendPluginOrchestrator.d.ts +64 -0
- package/dist/frontend/FrontendPluginOrchestrator.d.ts.map +1 -0
- package/dist/frontend/FrontendPluginOrchestrator.js +167 -0
- package/dist/frontend/FrontendPluginOrchestrator.js.map +1 -0
- package/dist/frontend/SiteResolver.d.ts +33 -0
- package/dist/frontend/SiteResolver.d.ts.map +1 -0
- package/dist/frontend/SiteResolver.js +53 -0
- package/dist/frontend/SiteResolver.js.map +1 -0
- package/dist/frontend/StaticMountRegistry.d.ts +36 -0
- package/dist/frontend/StaticMountRegistry.d.ts.map +1 -0
- package/dist/frontend/StaticMountRegistry.js +94 -0
- package/dist/frontend/StaticMountRegistry.js.map +1 -0
- package/dist/frontend/index.d.ts +7 -0
- package/dist/frontend/index.d.ts.map +1 -0
- package/{src → dist}/frontend/index.js +4 -2
- package/dist/frontend/index.js.map +1 -0
- package/dist/frontend/pathUtils.d.ts +8 -0
- package/dist/frontend/pathUtils.d.ts.map +1 -0
- package/dist/frontend/pathUtils.js +17 -0
- package/dist/frontend/pathUtils.js.map +1 -0
- package/dist/frontend/plugins/index.d.ts +2 -0
- package/dist/frontend/plugins/index.d.ts.map +1 -0
- package/{src → dist}/frontend/plugins/index.js +1 -1
- package/dist/frontend/plugins/index.js.map +1 -0
- package/dist/frontend/plugins/viteFrontend.d.ts +51 -0
- package/dist/frontend/plugins/viteFrontend.d.ts.map +1 -0
- package/dist/frontend/plugins/viteFrontend.js +134 -0
- package/dist/frontend/plugins/viteFrontend.js.map +1 -0
- package/dist/frontend/types.d.ts +25 -0
- package/dist/frontend/types.d.ts.map +1 -0
- package/dist/frontend/types.js +2 -0
- package/dist/frontend/types.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/internals.d.ts +21 -0
- package/dist/internals.d.ts.map +1 -0
- package/{src → dist}/internals.js +12 -14
- package/dist/internals.js.map +1 -0
- package/dist/plugins/PluginManager.d.ts +209 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -0
- package/dist/plugins/PluginManager.js +365 -0
- package/dist/plugins/PluginManager.js.map +1 -0
- package/dist/plugins/ScopedPostgres.d.ts +78 -0
- package/dist/plugins/ScopedPostgres.d.ts.map +1 -0
- package/dist/plugins/ScopedPostgres.js +190 -0
- package/dist/plugins/ScopedPostgres.js.map +1 -0
- package/dist/plugins/ScopedRedis.d.ts +88 -0
- package/dist/plugins/ScopedRedis.d.ts.map +1 -0
- package/dist/plugins/ScopedRedis.js +169 -0
- package/dist/plugins/ScopedRedis.js.map +1 -0
- package/dist/plugins/index.d.ts +289 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +1942 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/types.d.ts +59 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +2 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/registry/ServiceRegistry.d.ts +305 -0
- package/dist/registry/ServiceRegistry.d.ts.map +1 -0
- package/dist/registry/ServiceRegistry.js +735 -0
- package/dist/registry/ServiceRegistry.js.map +1 -0
- package/dist/scaling/ScaleAdvisor.d.ts +214 -0
- package/dist/scaling/ScaleAdvisor.d.ts.map +1 -0
- package/dist/scaling/ScaleAdvisor.js +526 -0
- package/dist/scaling/ScaleAdvisor.js.map +1 -0
- package/dist/services/Service.d.ts +164 -0
- package/dist/services/Service.d.ts.map +1 -0
- package/dist/services/Service.js +106 -0
- package/dist/services/Service.js.map +1 -0
- package/dist/services/worker-bootstrap.d.ts +15 -0
- package/dist/services/worker-bootstrap.d.ts.map +1 -0
- package/dist/services/worker-bootstrap.js +744 -0
- package/dist/services/worker-bootstrap.js.map +1 -0
- package/dist/templates/auth-service.d.ts +42 -0
- package/dist/templates/auth-service.d.ts.map +1 -0
- package/dist/templates/auth-service.js +54 -0
- package/dist/templates/auth-service.js.map +1 -0
- package/dist/templates/identity-service.d.ts +50 -0
- package/dist/templates/identity-service.d.ts.map +1 -0
- package/dist/templates/identity-service.js +62 -0
- package/dist/templates/identity-service.js.map +1 -0
- package/dist/types/contract.d.ts +120 -0
- package/dist/types/contract.d.ts.map +1 -0
- package/dist/types/contract.js +69 -0
- package/dist/types/contract.js.map +1 -0
- package/package.json +78 -20
- package/src/core/DirectMessageBus.js +0 -364
- package/src/core/EndpointResolver.js +0 -259
- package/src/core/ForgeContext.js +0 -2236
- package/src/core/ForgeHost.js +0 -122
- package/src/core/ForgePlatform.js +0 -145
- package/src/core/Ingress.js +0 -768
- package/src/core/Interceptors.js +0 -420
- package/src/core/MessageBus.js +0 -321
- package/src/core/Prometheus.js +0 -305
- package/src/core/RequestContext.js +0 -413
- package/src/core/RoutingStrategy.js +0 -330
- package/src/core/Supervisor.js +0 -1349
- package/src/core/ThreadAllocator.js +0 -196
- package/src/core/WorkerChannelManager.js +0 -879
- package/src/core/config.js +0 -637
- package/src/core/host-config.js +0 -311
- package/src/core/network-utils.js +0 -166
- package/src/core/platform-config.js +0 -308
- package/src/decorators/ServiceProxy.js +0 -904
- package/src/decorators/index.js +0 -571
- package/src/deploy/NginxGenerator.js +0 -865
- package/src/deploy/PlatformManifestGenerator.js +0 -96
- package/src/deploy/RouteManifestGenerator.js +0 -112
- package/src/deploy/index.js +0 -984
- package/src/frontend/FrontendDevLifecycle.js +0 -65
- package/src/frontend/FrontendPluginOrchestrator.js +0 -187
- package/src/frontend/SiteResolver.js +0 -63
- package/src/frontend/StaticMountRegistry.js +0 -90
- package/src/frontend/plugins/viteFrontend.js +0 -79
- package/src/frontend/types.js +0 -35
- package/src/index.js +0 -58
- package/src/plugins/PluginManager.js +0 -537
- package/src/plugins/ScopedPostgres.js +0 -192
- package/src/plugins/ScopedRedis.js +0 -142
- package/src/plugins/index.js +0 -1756
- package/src/registry/ServiceRegistry.js +0 -797
- package/src/scaling/ScaleAdvisor.js +0 -442
- package/src/services/Service.js +0 -195
- package/src/services/worker-bootstrap.js +0 -679
- package/src/templates/auth-service.js +0 -65
- package/src/templates/identity-service.js +0 -75
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network utility functions for ThreadForge.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from ForgeContext.js (A10) so other modules can reuse
|
|
5
|
+
* isPrivateNetwork, matchCIDR, ipToInt, and isTrustedProxy without
|
|
6
|
+
* pulling in the full ForgeContext dependency graph.
|
|
7
|
+
*/
|
|
8
|
+
// P12: Cache parsed FORGE_TRUSTED_NETWORKS — re-parse only when the env var changes
|
|
9
|
+
let _trustedNetworksRaw;
|
|
10
|
+
let _trustedNetworksParsed = [];
|
|
11
|
+
function _getTrustedNetworks() {
|
|
12
|
+
const raw = process.env.FORGE_TRUSTED_NETWORKS;
|
|
13
|
+
if (raw === _trustedNetworksRaw)
|
|
14
|
+
return _trustedNetworksParsed;
|
|
15
|
+
_trustedNetworksRaw = raw;
|
|
16
|
+
if (!raw) {
|
|
17
|
+
_trustedNetworksParsed = [];
|
|
18
|
+
return _trustedNetworksParsed;
|
|
19
|
+
}
|
|
20
|
+
const result = [];
|
|
21
|
+
for (const cidr of raw.split(",")) {
|
|
22
|
+
const trimmed = cidr.trim();
|
|
23
|
+
if (!trimmed)
|
|
24
|
+
continue;
|
|
25
|
+
if (trimmed.includes(":")) {
|
|
26
|
+
throw new Error(`FORGE_TRUSTED_NETWORKS contains IPv6 entry "${trimmed}" which is not supported. Only IPv4 CIDRs are supported. Remove IPv6 entries or use IPv4-mapped addresses.`);
|
|
27
|
+
}
|
|
28
|
+
result.push(trimmed);
|
|
29
|
+
}
|
|
30
|
+
_trustedNetworksParsed = result;
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Convert an IPv4 dotted-quad string to a 32-bit unsigned integer.
|
|
35
|
+
* Returns null if the address is malformed.
|
|
36
|
+
*/
|
|
37
|
+
export function ipToInt(ip) {
|
|
38
|
+
const parts = ip.split(".");
|
|
39
|
+
if (parts.length !== 4)
|
|
40
|
+
return null;
|
|
41
|
+
let result = 0;
|
|
42
|
+
for (const part of parts) {
|
|
43
|
+
const n = parseInt(part, 10);
|
|
44
|
+
if (Number.isNaN(n) || n < 0 || n > 255)
|
|
45
|
+
return null;
|
|
46
|
+
result = (result << 8) | n;
|
|
47
|
+
}
|
|
48
|
+
return result >>> 0;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Basic CIDR match for IPv4. Matches address against prefix/length.
|
|
52
|
+
*/
|
|
53
|
+
export function matchCIDR(addr, cidr) {
|
|
54
|
+
const [prefix, lenStr] = cidr.split("/");
|
|
55
|
+
if (!prefix || !lenStr)
|
|
56
|
+
return false;
|
|
57
|
+
const maskLen = parseInt(lenStr, 10);
|
|
58
|
+
if (Number.isNaN(maskLen) || maskLen < 0 || maskLen > 32)
|
|
59
|
+
return false;
|
|
60
|
+
const addrNum = ipToInt(addr);
|
|
61
|
+
const prefixNum = ipToInt(prefix);
|
|
62
|
+
if (addrNum === null || prefixNum === null)
|
|
63
|
+
return false;
|
|
64
|
+
const mask = maskLen === 0 ? 0 : (~0 << (32 - maskLen)) >>> 0;
|
|
65
|
+
return (addrNum & mask) === (prefixNum & mask);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Normalize a raw socket address by stripping IPv6 zone IDs and
|
|
69
|
+
* IPv6-mapped IPv4 prefixes.
|
|
70
|
+
*/
|
|
71
|
+
export function normalizeAddress(address) {
|
|
72
|
+
// Strip IPv6 zone ID suffix (e.g., %eth0)
|
|
73
|
+
const noZone = address.split("%")[0];
|
|
74
|
+
// S5: Tighten IPv6-mapped IPv4 regex — require exactly 5 zero groups before ffff:
|
|
75
|
+
// Matches forms like 0:0:0:0:0:ffff:x.x.x.x or 0000:0000:0000:0000:0000:ffff:x.x.x.x
|
|
76
|
+
return noZone
|
|
77
|
+
.toLowerCase()
|
|
78
|
+
.replace(/^(?:0{1,4}:){5}(?:0{1,4}:)?ffff:/, "")
|
|
79
|
+
.replace(/^::ffff:/, "");
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check if a remote address is from a private/trusted network.
|
|
83
|
+
*
|
|
84
|
+
* Covers RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16),
|
|
85
|
+
* loopback (127.0.0.0/8, ::1), IPv6-mapped IPv4 (::ffff:x.x.x.x),
|
|
86
|
+
* and custom trusted networks via FORGE_TRUSTED_NETWORKS env var.
|
|
87
|
+
*/
|
|
88
|
+
export function isPrivateNetwork(address) {
|
|
89
|
+
if (!address)
|
|
90
|
+
return false;
|
|
91
|
+
const addr = normalizeAddress(address);
|
|
92
|
+
// Loopback
|
|
93
|
+
if (addr === "127.0.0.1" || addr === "::1" || addr.startsWith("127."))
|
|
94
|
+
return true;
|
|
95
|
+
// IPv6 link-local (fe80::/10)
|
|
96
|
+
if (/^fe[89ab][0-9a-f]:/i.test(addr))
|
|
97
|
+
return true;
|
|
98
|
+
// IPv6 unique local (fc00::/7)
|
|
99
|
+
if (/^f[cd][0-9a-f]{2}:/i.test(addr))
|
|
100
|
+
return true;
|
|
101
|
+
// RFC 1918 private ranges
|
|
102
|
+
if (addr.startsWith("10."))
|
|
103
|
+
return true;
|
|
104
|
+
if (addr.startsWith("192.168."))
|
|
105
|
+
return true;
|
|
106
|
+
// 172.16.0.0/12 — covers 172.16.x.x through 172.31.x.x
|
|
107
|
+
if (addr.startsWith("172.")) {
|
|
108
|
+
const second = parseInt(addr.split(".")[1], 10);
|
|
109
|
+
if (second >= 16 && second <= 31)
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
// Link-local (169.254.0.0/16)
|
|
113
|
+
if (addr.startsWith("169.254."))
|
|
114
|
+
return true;
|
|
115
|
+
// P12: Use cached trusted networks (re-parsed only when env var changes)
|
|
116
|
+
for (const cidr of _getTrustedNetworks()) {
|
|
117
|
+
if (matchCIDR(addr, cidr))
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Check if a remote address is a trusted proxy.
|
|
124
|
+
* Only trusts addresses listed in FORGE_TRUSTED_PROXIES env var.
|
|
125
|
+
*/
|
|
126
|
+
export function isTrustedProxy(address) {
|
|
127
|
+
const trusted = process.env.FORGE_TRUSTED_PROXIES;
|
|
128
|
+
if (!trusted)
|
|
129
|
+
return false;
|
|
130
|
+
if (!address)
|
|
131
|
+
return false;
|
|
132
|
+
const addr = normalizeAddress(address);
|
|
133
|
+
for (const entry of trusted.split(",")) {
|
|
134
|
+
const trimmed = entry.trim();
|
|
135
|
+
if (trimmed.includes("/")) {
|
|
136
|
+
if (matchCIDR(addr, trimmed))
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
else if (addr === trimmed) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=network-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-utils.js","sourceRoot":"","sources":["../../src/core/network-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform Mode Configuration
|
|
3
|
+
*
|
|
4
|
+
* Transforms a user-facing `platform.apps` config into ForgeHost's
|
|
5
|
+
* internal `projects` format. Platform Mode is a config transformation
|
|
6
|
+
* layer on top of ForgeHost — it reuses resolveHostConfig() as the engine.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
*
|
|
10
|
+
* import { definePlatform } from 'threadforge';
|
|
11
|
+
*
|
|
12
|
+
* export default definePlatform({
|
|
13
|
+
* platform: {
|
|
14
|
+
* globalAuth: true,
|
|
15
|
+
* apps: {
|
|
16
|
+
* coolapp: {
|
|
17
|
+
* domains: ['coolapp.io'],
|
|
18
|
+
* services: ['coolapp-api'],
|
|
19
|
+
* schema: 'coolapp',
|
|
20
|
+
* },
|
|
21
|
+
* },
|
|
22
|
+
* },
|
|
23
|
+
* plugins: [redis(), postgres()],
|
|
24
|
+
* identity: { entry: './services/identity.js', type: 'edge', port: 3001 },
|
|
25
|
+
* auth: { entry: './services/auth.js', type: 'edge', port: 3002 },
|
|
26
|
+
* 'coolapp-api': { entry: './apps/coolapp/api.js', type: 'edge', port: 4001 },
|
|
27
|
+
* });
|
|
28
|
+
*/
|
|
29
|
+
import type { NormalizedConfig, RawServiceConfig } from "./config.js";
|
|
30
|
+
interface ForgeProxyConfig {
|
|
31
|
+
enabled?: boolean;
|
|
32
|
+
host?: string;
|
|
33
|
+
port?: number;
|
|
34
|
+
keepalive?: number;
|
|
35
|
+
}
|
|
36
|
+
interface FrontendInput {
|
|
37
|
+
plugin?: string;
|
|
38
|
+
root?: string;
|
|
39
|
+
outDir?: string;
|
|
40
|
+
basePath?: string;
|
|
41
|
+
spaFallback?: boolean;
|
|
42
|
+
env?: Record<string, string>;
|
|
43
|
+
options?: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
interface NormalizedFrontend {
|
|
46
|
+
plugin: string;
|
|
47
|
+
root: string;
|
|
48
|
+
outDir: string;
|
|
49
|
+
basePath: string;
|
|
50
|
+
spaFallback: boolean;
|
|
51
|
+
env: Record<string, string>;
|
|
52
|
+
options: Record<string, unknown>;
|
|
53
|
+
}
|
|
54
|
+
interface AppConfig {
|
|
55
|
+
domains?: string[];
|
|
56
|
+
domain?: string;
|
|
57
|
+
services?: string[];
|
|
58
|
+
config?: string;
|
|
59
|
+
frontend?: FrontendInput;
|
|
60
|
+
static?: string | null;
|
|
61
|
+
schema?: string;
|
|
62
|
+
}
|
|
63
|
+
interface PlatformBlock {
|
|
64
|
+
globalAuth?: boolean;
|
|
65
|
+
apps: Record<string, AppConfig>;
|
|
66
|
+
domain?: string;
|
|
67
|
+
basePort?: number;
|
|
68
|
+
metricsPort?: number;
|
|
69
|
+
forgeProxy?: boolean | ForgeProxyConfig | null | undefined;
|
|
70
|
+
}
|
|
71
|
+
export interface PlatformConfig {
|
|
72
|
+
platform: PlatformBlock;
|
|
73
|
+
plugins?: unknown[];
|
|
74
|
+
frontendPlugins?: unknown[];
|
|
75
|
+
[key: string]: unknown;
|
|
76
|
+
}
|
|
77
|
+
export interface DefinedPlatformConfig {
|
|
78
|
+
_isPlatformConfig: true;
|
|
79
|
+
_raw: PlatformConfig;
|
|
80
|
+
platform: PlatformBlock;
|
|
81
|
+
plugins: unknown[];
|
|
82
|
+
frontendPlugins: unknown[];
|
|
83
|
+
}
|
|
84
|
+
interface HostConfigInput {
|
|
85
|
+
domain: string | null;
|
|
86
|
+
basePort: number;
|
|
87
|
+
metricsPort: number;
|
|
88
|
+
projects: Record<string, ProjectEntry>;
|
|
89
|
+
shared: Record<string, RawServiceConfig>;
|
|
90
|
+
plugins: unknown[];
|
|
91
|
+
frontendPlugins: unknown[];
|
|
92
|
+
}
|
|
93
|
+
interface ProjectEntry {
|
|
94
|
+
domain: string;
|
|
95
|
+
domains: string[];
|
|
96
|
+
schema: string;
|
|
97
|
+
static: string | null;
|
|
98
|
+
frontend: NormalizedFrontend | null;
|
|
99
|
+
services: Record<string, RawServiceConfig> | undefined;
|
|
100
|
+
config: string | undefined;
|
|
101
|
+
}
|
|
102
|
+
export interface ResolvedPlatformConfig extends NormalizedConfig {
|
|
103
|
+
_isPlatformMode: boolean;
|
|
104
|
+
_isHostMode: boolean;
|
|
105
|
+
_hostMeta: unknown;
|
|
106
|
+
_hostDomain: string | null;
|
|
107
|
+
_sites: Record<string, unknown>;
|
|
108
|
+
_platformConfig: PlatformBlock;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Normalize an app's domain(s) to an array.
|
|
112
|
+
* Accepts either `domains: [...]` or `domain: '...'`.
|
|
113
|
+
*/
|
|
114
|
+
export declare function resolveAppDomains(app: {
|
|
115
|
+
domains?: string[];
|
|
116
|
+
domain?: string;
|
|
117
|
+
}): string[];
|
|
118
|
+
/**
|
|
119
|
+
* Validate the platform config shape.
|
|
120
|
+
*
|
|
121
|
+
* @throws {Error} On invalid config
|
|
122
|
+
*/
|
|
123
|
+
export declare function validatePlatformConfig(config: unknown): asserts config is PlatformConfig;
|
|
124
|
+
/**
|
|
125
|
+
* Transform platform config into ForgeHost's internal projects format.
|
|
126
|
+
*
|
|
127
|
+
* Maps platform.apps -> hostConfig.projects, preserving custom schemas
|
|
128
|
+
* and auto-injecting identity+auth when globalAuth is enabled.
|
|
129
|
+
*/
|
|
130
|
+
export declare function transformToHostConfig(config: PlatformConfig): HostConfigInput;
|
|
131
|
+
/**
|
|
132
|
+
* Define a Platform Mode config.
|
|
133
|
+
*
|
|
134
|
+
* Validates the config and returns a marked config object.
|
|
135
|
+
*/
|
|
136
|
+
export declare function definePlatform(config: PlatformConfig): DefinedPlatformConfig;
|
|
137
|
+
/**
|
|
138
|
+
* Resolve a platform config fully: transform -> resolveHostConfig -> defineServices.
|
|
139
|
+
*/
|
|
140
|
+
export declare function resolveAndDefinePlatform(config: DefinedPlatformConfig | PlatformConfig): Promise<ResolvedPlatformConfig>;
|
|
141
|
+
export {};
|
|
142
|
+
//# sourceMappingURL=platform-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-config.d.ts","sourceRoot":"","sources":["../../src/core/platform-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform Mode Configuration
|
|
3
|
+
*
|
|
4
|
+
* Transforms a user-facing `platform.apps` config into ForgeHost's
|
|
5
|
+
* internal `projects` format. Platform Mode is a config transformation
|
|
6
|
+
* layer on top of ForgeHost — it reuses resolveHostConfig() as the engine.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
*
|
|
10
|
+
* import { definePlatform } from 'threadforge';
|
|
11
|
+
*
|
|
12
|
+
* export default definePlatform({
|
|
13
|
+
* platform: {
|
|
14
|
+
* globalAuth: true,
|
|
15
|
+
* apps: {
|
|
16
|
+
* coolapp: {
|
|
17
|
+
* domains: ['coolapp.io'],
|
|
18
|
+
* services: ['coolapp-api'],
|
|
19
|
+
* schema: 'coolapp',
|
|
20
|
+
* },
|
|
21
|
+
* },
|
|
22
|
+
* },
|
|
23
|
+
* plugins: [redis(), postgres()],
|
|
24
|
+
* identity: { entry: './services/identity.js', type: 'edge', port: 3001 },
|
|
25
|
+
* auth: { entry: './services/auth.js', type: 'edge', port: 3002 },
|
|
26
|
+
* 'coolapp-api': { entry: './apps/coolapp/api.js', type: 'edge', port: 4001 },
|
|
27
|
+
* });
|
|
28
|
+
*/
|
|
29
|
+
import { ServiceType } from "./config-enums.js";
|
|
30
|
+
import { defineServices } from "./config.js";
|
|
31
|
+
import { resolveHostConfig } from "./host-config.js";
|
|
32
|
+
const APP_ID_RE = /^[a-z][a-z0-9_-]*$/;
|
|
33
|
+
const BASE_PATH_RE = /^\/[^\s?#]*$/;
|
|
34
|
+
// ── Helpers ─────────────────────────────────────────────────────────
|
|
35
|
+
function isPlainObject(value) {
|
|
36
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
37
|
+
}
|
|
38
|
+
function validateForgeProxyConfig(forgeProxy) {
|
|
39
|
+
if (forgeProxy === undefined || forgeProxy === null || forgeProxy === true) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (forgeProxy === false) {
|
|
43
|
+
throw new Error("platform.forgeProxy cannot be false in platform mode");
|
|
44
|
+
}
|
|
45
|
+
if (!isPlainObject(forgeProxy)) {
|
|
46
|
+
throw new Error("platform.forgeProxy must be true or an object");
|
|
47
|
+
}
|
|
48
|
+
if (forgeProxy.enabled === false) {
|
|
49
|
+
throw new Error("platform.forgeProxy.enabled cannot be false in platform mode");
|
|
50
|
+
}
|
|
51
|
+
if (forgeProxy.enabled !== undefined && forgeProxy.enabled !== true) {
|
|
52
|
+
throw new Error("platform.forgeProxy.enabled must be true when provided");
|
|
53
|
+
}
|
|
54
|
+
if (forgeProxy.host !== undefined) {
|
|
55
|
+
if (typeof forgeProxy.host !== "string" || forgeProxy.host.trim() === "") {
|
|
56
|
+
throw new Error("platform.forgeProxy.host must be a non-empty string when provided");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (forgeProxy.port !== undefined) {
|
|
60
|
+
if (!Number.isInteger(forgeProxy.port) || forgeProxy.port < 1 || forgeProxy.port > 65535) {
|
|
61
|
+
throw new Error("platform.forgeProxy.port must be an integer between 1 and 65535");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (forgeProxy.keepalive !== undefined) {
|
|
65
|
+
if (!Number.isInteger(forgeProxy.keepalive) || forgeProxy.keepalive < 1) {
|
|
66
|
+
throw new Error("platform.forgeProxy.keepalive must be a positive integer");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function normalizeFrontendConfig(appId, frontend) {
|
|
71
|
+
if (!isPlainObject(frontend)) {
|
|
72
|
+
throw new Error(`App "${appId}" frontend must be an object`);
|
|
73
|
+
}
|
|
74
|
+
if (typeof frontend.plugin !== "string" || frontend.plugin.trim() === "") {
|
|
75
|
+
throw new Error(`App "${appId}" frontend.plugin must be a non-empty string`);
|
|
76
|
+
}
|
|
77
|
+
if (typeof frontend.root !== "string" || frontend.root.trim() === "") {
|
|
78
|
+
throw new Error(`App "${appId}" frontend.root must be a non-empty string`);
|
|
79
|
+
}
|
|
80
|
+
if (frontend.outDir !== undefined &&
|
|
81
|
+
(typeof frontend.outDir !== "string" || frontend.outDir.trim() === "")) {
|
|
82
|
+
throw new Error(`App "${appId}" frontend.outDir must be a non-empty string when provided`);
|
|
83
|
+
}
|
|
84
|
+
if (frontend.basePath !== undefined) {
|
|
85
|
+
if (typeof frontend.basePath !== "string" || !BASE_PATH_RE.test(frontend.basePath)) {
|
|
86
|
+
throw new Error(`App "${appId}" frontend.basePath must start with "/" and cannot include query strings or fragments`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (frontend.spaFallback !== undefined && typeof frontend.spaFallback !== "boolean") {
|
|
90
|
+
throw new Error(`App "${appId}" frontend.spaFallback must be a boolean when provided`);
|
|
91
|
+
}
|
|
92
|
+
if (frontend.env !== undefined && !isPlainObject(frontend.env)) {
|
|
93
|
+
throw new Error(`App "${appId}" frontend.env must be an object when provided`);
|
|
94
|
+
}
|
|
95
|
+
if (frontend.options !== undefined && !isPlainObject(frontend.options)) {
|
|
96
|
+
throw new Error(`App "${appId}" frontend.options must be an object when provided`);
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
plugin: frontend.plugin,
|
|
100
|
+
root: frontend.root,
|
|
101
|
+
outDir: frontend.outDir ?? `.threadforge/build/${appId}`,
|
|
102
|
+
basePath: frontend.basePath ?? "/",
|
|
103
|
+
spaFallback: frontend.spaFallback ?? true,
|
|
104
|
+
env: frontend.env ?? {},
|
|
105
|
+
options: frontend.options ?? {},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// ── Exports ─────────────────────────────────────────────────────────
|
|
109
|
+
/**
|
|
110
|
+
* Normalize an app's domain(s) to an array.
|
|
111
|
+
* Accepts either `domains: [...]` or `domain: '...'`.
|
|
112
|
+
*/
|
|
113
|
+
export function resolveAppDomains(app) {
|
|
114
|
+
if (app.domains)
|
|
115
|
+
return app.domains;
|
|
116
|
+
if (app.domain)
|
|
117
|
+
return [app.domain];
|
|
118
|
+
return [];
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Validate the platform config shape.
|
|
122
|
+
*
|
|
123
|
+
* @throws {Error} On invalid config
|
|
124
|
+
*/
|
|
125
|
+
export function validatePlatformConfig(config) {
|
|
126
|
+
if (!config || typeof config !== "object") {
|
|
127
|
+
throw new Error("definePlatform() requires a config object");
|
|
128
|
+
}
|
|
129
|
+
const cfg = config;
|
|
130
|
+
if (!cfg.platform || typeof cfg.platform !== "object") {
|
|
131
|
+
throw new Error("definePlatform() requires a platform block");
|
|
132
|
+
}
|
|
133
|
+
const platform = cfg.platform;
|
|
134
|
+
const apps = platform.apps;
|
|
135
|
+
if (!apps || typeof apps !== "object") {
|
|
136
|
+
throw new Error("platform.apps must be a non-empty object");
|
|
137
|
+
}
|
|
138
|
+
validateForgeProxyConfig(platform.forgeProxy);
|
|
139
|
+
const appIds = Object.keys(apps);
|
|
140
|
+
if (appIds.length === 0) {
|
|
141
|
+
throw new Error("platform.apps must contain at least one app");
|
|
142
|
+
}
|
|
143
|
+
const schemas = new Set();
|
|
144
|
+
for (const appId of appIds) {
|
|
145
|
+
if (!APP_ID_RE.test(appId)) {
|
|
146
|
+
throw new Error(`Invalid app ID "${appId}": must start with a lowercase letter and contain only lowercase letters, digits, hyphens, and underscores`);
|
|
147
|
+
}
|
|
148
|
+
const app = apps[appId];
|
|
149
|
+
if (!app || typeof app !== "object") {
|
|
150
|
+
throw new Error(`App "${appId}" must be an object`);
|
|
151
|
+
}
|
|
152
|
+
const appObj = app;
|
|
153
|
+
if (!appObj.domains && !appObj.domain) {
|
|
154
|
+
throw new Error(`App "${appId}" must have a domains array`);
|
|
155
|
+
}
|
|
156
|
+
const domains = resolveAppDomains(appObj);
|
|
157
|
+
if (domains.length === 0) {
|
|
158
|
+
throw new Error(`App "${appId}" must have at least one domain`);
|
|
159
|
+
}
|
|
160
|
+
if (!appObj.services && !appObj.config) {
|
|
161
|
+
throw new Error(`App "${appId}" must have either services or config`);
|
|
162
|
+
}
|
|
163
|
+
if (appObj.frontend) {
|
|
164
|
+
normalizeFrontendConfig(appId, appObj.frontend);
|
|
165
|
+
}
|
|
166
|
+
const schema = appObj.schema ?? appId;
|
|
167
|
+
if (schemas.has(schema)) {
|
|
168
|
+
throw new Error(`Duplicate schema "${schema}" — each app must have a unique schema`);
|
|
169
|
+
}
|
|
170
|
+
schemas.add(schema);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Transform platform config into ForgeHost's internal projects format.
|
|
175
|
+
*
|
|
176
|
+
* Maps platform.apps -> hostConfig.projects, preserving custom schemas
|
|
177
|
+
* and auto-injecting identity+auth when globalAuth is enabled.
|
|
178
|
+
*/
|
|
179
|
+
export function transformToHostConfig(config) {
|
|
180
|
+
const { platform } = config;
|
|
181
|
+
const apps = platform.apps;
|
|
182
|
+
const globalAuth = platform.globalAuth ?? false;
|
|
183
|
+
// Collect all service names claimed by apps
|
|
184
|
+
const claimedServices = new Set();
|
|
185
|
+
for (const app of Object.values(apps)) {
|
|
186
|
+
for (const svcName of app.services ?? []) {
|
|
187
|
+
claimedServices.add(svcName);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Build shared services: any service definition in config that is not
|
|
191
|
+
// claimed by an app and not a reserved top-level key
|
|
192
|
+
const shared = {};
|
|
193
|
+
for (const [key, value] of Object.entries(config)) {
|
|
194
|
+
if (key === "platform" || key === "plugins")
|
|
195
|
+
continue;
|
|
196
|
+
if (claimedServices.has(key))
|
|
197
|
+
continue;
|
|
198
|
+
if (typeof value !== "object" || value === null)
|
|
199
|
+
continue;
|
|
200
|
+
const svc = value;
|
|
201
|
+
if (!svc.entry && !svc.type)
|
|
202
|
+
continue;
|
|
203
|
+
shared[key] = value;
|
|
204
|
+
}
|
|
205
|
+
// Auto-inject identity + auth as shared services when globalAuth is enabled
|
|
206
|
+
if (globalAuth) {
|
|
207
|
+
if (!shared.identity) {
|
|
208
|
+
shared.identity = {
|
|
209
|
+
entry: "./shared/identity.js",
|
|
210
|
+
type: ServiceType.EDGE,
|
|
211
|
+
port: 3001,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
if (!shared.auth) {
|
|
215
|
+
shared.auth = {
|
|
216
|
+
entry: "./shared/auth.js",
|
|
217
|
+
type: ServiceType.EDGE,
|
|
218
|
+
port: 3002,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// Build projects map from apps
|
|
223
|
+
const projects = {};
|
|
224
|
+
for (const [appId, app] of Object.entries(apps)) {
|
|
225
|
+
const domains = resolveAppDomains(app);
|
|
226
|
+
// Build inline service map from claimed service names
|
|
227
|
+
const inlineServices = {};
|
|
228
|
+
for (const svcName of app.services ?? []) {
|
|
229
|
+
const svcConfig = config[svcName];
|
|
230
|
+
if (svcConfig) {
|
|
231
|
+
inlineServices[svcName] = svcConfig;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const hasInlineServices = Object.keys(inlineServices).length > 0;
|
|
235
|
+
const frontend = app.frontend ? normalizeFrontendConfig(appId, app.frontend) : null;
|
|
236
|
+
if (frontend && app.static) {
|
|
237
|
+
console.warn(`[ThreadForge] App "${appId}" defines both "frontend" and legacy "static". ` +
|
|
238
|
+
`Using frontend plugin config and ignoring "static".`);
|
|
239
|
+
}
|
|
240
|
+
projects[appId] = {
|
|
241
|
+
domain: domains[0],
|
|
242
|
+
domains,
|
|
243
|
+
schema: app.schema ?? appId,
|
|
244
|
+
static: frontend ? null : (app.static ?? null),
|
|
245
|
+
frontend,
|
|
246
|
+
services: hasInlineServices ? inlineServices : undefined,
|
|
247
|
+
config: app.config,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
domain: platform.domain ?? null,
|
|
252
|
+
basePort: platform.basePort ?? 3200,
|
|
253
|
+
metricsPort: platform.metricsPort ?? 9090,
|
|
254
|
+
projects,
|
|
255
|
+
shared,
|
|
256
|
+
plugins: config.plugins ?? [],
|
|
257
|
+
frontendPlugins: config.frontendPlugins ?? [],
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Define a Platform Mode config.
|
|
262
|
+
*
|
|
263
|
+
* Validates the config and returns a marked config object.
|
|
264
|
+
*/
|
|
265
|
+
export function definePlatform(config) {
|
|
266
|
+
validatePlatformConfig(config);
|
|
267
|
+
return {
|
|
268
|
+
_isPlatformConfig: true,
|
|
269
|
+
_raw: config,
|
|
270
|
+
platform: config.platform,
|
|
271
|
+
plugins: config.plugins ?? [],
|
|
272
|
+
frontendPlugins: config.frontendPlugins ?? [],
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Resolve a platform config fully: transform -> resolveHostConfig -> defineServices.
|
|
277
|
+
*/
|
|
278
|
+
export async function resolveAndDefinePlatform(config) {
|
|
279
|
+
const raw = "_isPlatformConfig" in config && config._isPlatformConfig
|
|
280
|
+
? config._raw
|
|
281
|
+
: config;
|
|
282
|
+
validatePlatformConfig(raw);
|
|
283
|
+
const hostConfig = transformToHostConfig(raw);
|
|
284
|
+
const resolved = await resolveHostConfig(hostConfig);
|
|
285
|
+
const result = defineServices(resolved.services, {
|
|
286
|
+
plugins: resolved.plugins,
|
|
287
|
+
frontendPlugins: resolved.frontendPlugins,
|
|
288
|
+
sites: resolved.sites,
|
|
289
|
+
metricsPort: resolved.metricsPort,
|
|
290
|
+
});
|
|
291
|
+
result._isPlatformMode = true;
|
|
292
|
+
result._isHostMode = true;
|
|
293
|
+
result._hostMeta = resolved.hostMeta;
|
|
294
|
+
result._hostDomain = resolved.domain;
|
|
295
|
+
result._sites = resolved.sites;
|
|
296
|
+
result._platformConfig = raw.platform;
|
|
297
|
+
return result;
|
|
298
|
+
}
|
|
299
|
+
//# sourceMappingURL=platform-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-config.js","sourceRoot":"","sources":["../../src/core/platform-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,SAAS,GAAG,oBAAoB,CAAC;AACvC,MAAM,YAAY,GAAG,cAAc,CAAC;AA8FpC,uEAAuE;AAEvE,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,wBAAwB,CAAC,UAAmB;IACnD,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QAC3E,OAAO;IACT,CAAC;IACD,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,UAAU,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IACD,IAAI,UAAU,CAAC,OAAO,KAAK,SAAS,IAAI,UAAU,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ,IAAK,UAAU,CAAC,IAAe,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACrF,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,IAAK,UAAU,CAAC,IAAe,GAAG,CAAC,IAAK,UAAU,CAAC,IAAe,GAAG,KAAK,EAAE,CAAC;YACjH,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IAED,IAAI,UAAU,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,IAAK,UAAU,CAAC,SAAoB,GAAG,CAAC,EAAE,CAAC;YACpF,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAa,EAAE,QAAiB;IAC/D,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,8BAA8B,CAAC,CAAC;IAC/D,CAAC;IAED,IAAI,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,IAAK,QAAQ,CAAC,MAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrF,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,8CAA8C,CAAC,CAAC;IAC/E,CAAC;IAED,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAK,QAAQ,CAAC,IAAe,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACjF,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,4CAA4C,CAAC,CAAC;IAC7E,CAAC;IAED,IACE,QAAQ,CAAC,MAAM,KAAK,SAAS;QAC7B,CAAC,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,IAAK,QAAQ,CAAC,MAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAClF,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,4DAA4D,CAAC,CAAC;IAC7F,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACpC,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAkB,CAAC,EAAE,CAAC;YAC7F,MAAM,IAAI,KAAK,CACb,QAAQ,KAAK,uFAAuF,CACrG,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,QAAQ,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACpF,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,wDAAwD,CAAC,CAAC;IACzF,CAAC;IAED,IAAI,QAAQ,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,gDAAgD,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,oDAAoD,CAAC,CAAC;IACrF,CAAC;IAED,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,MAAgB;QACjC,IAAI,EAAE,QAAQ,CAAC,IAAc;QAC7B,MAAM,EAAG,QAAQ,CAAC,MAA6B,IAAI,sBAAsB,KAAK,EAAE;QAChF,QAAQ,EAAG,QAAQ,CAAC,QAA+B,IAAI,GAAG;QAC1D,WAAW,EAAG,QAAQ,CAAC,WAAmC,IAAI,IAAI;QAClE,GAAG,EAAG,QAAQ,CAAC,GAA0C,IAAI,EAAE;QAC/D,OAAO,EAAG,QAAQ,CAAC,OAA+C,IAAI,EAAE;KACzE,CAAC;AACJ,CAAC;AAED,uEAAuE;AAEvE;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAA4C;IAC5E,IAAI,GAAG,CAAC,OAAO;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IACpC,IAAI,GAAG,CAAC,MAAM;QAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAe;IACpD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,GAAG,GAAG,MAAiC,CAAC;IAE9C,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAmC,CAAC;IACzD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;IAC3B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,wBAAwB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAE9C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAA+B,CAAC,CAAC;IAC5D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,mBAAmB,KAAK,4GAA4G,CACrI,CAAC;QACJ,CAAC;QAED,MAAM,GAAG,GAAI,IAAgC,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,qBAAqB,CAAC,CAAC;QACtD,CAAC;QAED,MAAM,MAAM,GAAG,GAA8B,CAAC;QAE9C,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,6BAA6B,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAiD,CAAC,CAAC;QACrF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,iCAAiC,CAAC,CAAC;QAClE,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,uCAAuC,CAAC,CAAC;QACxE,CAAC;QAED,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,uBAAuB,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,MAAM,GAAI,MAAM,CAAC,MAA6B,IAAI,KAAK,CAAC;QAC9D,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,qBAAqB,MAAM,wCAAwC,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAsB;IAC1D,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;IAC3B,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,IAAI,KAAK,CAAC;IAEhD,4CAA4C;IAC5C,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAC1C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;YACzC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,sEAAsE;IACtE,qDAAqD;IACrD,MAAM,MAAM,GAAqC,EAAE,CAAC;IACpD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,GAAG,KAAK,UAAU,IAAI,GAAG,KAAK,SAAS;YAAE,SAAS;QACtD,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QAC1D,MAAM,GAAG,GAAG,KAAgC,CAAC;QAC7C,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI;YAAE,SAAS;QACtC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAyB,CAAC;IAC1C,CAAC;IAED,4EAA4E;IAC5E,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrB,MAAM,CAAC,QAAQ,GAAG;gBAChB,KAAK,EAAE,sBAAsB;gBAC7B,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,IAAI,EAAE,IAAI;aACX,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,CAAC,IAAI,GAAG;gBACZ,KAAK,EAAE,kBAAkB;gBACzB,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,IAAI,EAAE,IAAI;aACX,CAAC;QACJ,CAAC;IACH,CAAC;IAED,+BAA+B;IAC/B,MAAM,QAAQ,GAAiC,EAAE,CAAC;IAClD,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAEvC,sDAAsD;QACtD,MAAM,cAAc,GAAqC,EAAE,CAAC;QAC5D,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;YACzC,MAAM,SAAS,GAAI,MAAkC,CAAC,OAAO,CAAC,CAAC;YAC/D,IAAI,SAAS,EAAE,CAAC;gBACd,cAAc,CAAC,OAAO,CAAC,GAAG,SAA6B,CAAC;YAC1D,CAAC;QACH,CAAC;QAED,MAAM,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,uBAAuB,CAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACpF,IAAI,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CACV,sBAAsB,KAAK,iDAAiD;gBAC1E,qDAAqD,CACxD,CAAC;QACJ,CAAC;QAED,QAAQ,CAAC,KAAK,CAAC,GAAG;YAChB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;YAClB,OAAO;YACP,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,KAAK;YAC3B,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC;YAC9C,QAAQ;YACR,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS;YACxD,MAAM,EAAE,GAAG,CAAC,MAAM;SACnB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,IAAI;QAC/B,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,IAAI;QACnC,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,IAAI;QACzC,QAAQ;QACR,MAAM;QACN,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;QAC7B,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,EAAE;KAC9C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAsB;IACnD,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE/B,OAAO;QACL,iBAAiB,EAAE,IAAI;QACvB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;QAC7B,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,EAAE;KAC9C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAA8C;IAE9C,MAAM,GAAG,GACP,mBAAmB,IAAI,MAAM,IAAI,MAAM,CAAC,iBAAiB;QACvD,CAAC,CAAE,MAAgC,CAAC,IAAI;QACxC,CAAC,CAAE,MAAyB,CAAC;IACjC,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAE5B,MAAM,UAAU,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,QAAQ,EAAE;QAC/C,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,eAAe,EAAE,QAAQ,CAAC,eAAe;QACzC,KAAK,EAAE,QAAQ,CAAC,KAA8C;QAC9D,WAAW,EAAE,QAAQ,CAAC,WAAW;KAClC,CAA2B,CAAC;IAE7B,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC;IAC9B,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC;IACrC,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC;IACrC,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,KAAgC,CAAC;IAC1D,MAAM,CAAC,eAAe,GAAG,GAAG,CAAC,QAAQ,CAAC;IAEtC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|