enigma-memory 0.1.18 → 0.1.22
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 +76 -24
- package/apps/cli/bin/enigma-desktop.mjs +140 -0
- package/apps/cli/bin/enigma-terminal.mjs +78 -0
- package/apps/cli/bin/enigma.mjs +1923 -285
- package/apps/desktop/electron-main.cjs +217 -0
- package/apps/desktop/package.json +12 -0
- package/apps/desktop/src/app.js +264 -7
- package/apps/desktop/src/index.html +3514 -1373
- package/apps/desktop/src/launch-electron.mjs +51 -0
- package/apps/desktop/src/server.mjs +2914 -0
- package/apps/desktop/src/styles.css +2972 -260
- package/apps/desktop/src/zk-browser-prove.mjs +53 -0
- package/apps/desktop/src/zk-state.mjs +1789 -0
- package/apps/gateway/bin/enigma-gateway.mjs +102 -5
- package/apps/gateway/src/server.mjs +271 -8
- package/apps/ios/EnigmaCore/Package.swift +12 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/EnigmaAPIClient.swift +227 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/Models.swift +278 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/PKCE.swift +96 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/PrivacyMinimizer.swift +187 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/ToolModels.swift +129 -0
- package/apps/ios/EnigmaCore/Tests/EnigmaCoreTests/EnigmaCoreTests.swift +42 -0
- package/apps/ios/EnigmaIOS/Enigma/AppModel.swift +346 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AccentColor.colorset/Contents.json +12 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AppIcon.appiconset/Contents.json +11 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AppIcon.appiconset/EnigmaAppIcon.png +0 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/Contents.json +3 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/LaunchBackground.colorset/Contents.json +12 -0
- package/apps/ios/EnigmaIOS/Enigma/ChatView.swift +181 -0
- package/apps/ios/EnigmaIOS/Enigma/CouncilView.swift +78 -0
- package/apps/ios/EnigmaIOS/Enigma/CreateView.swift +152 -0
- package/apps/ios/EnigmaIOS/Enigma/EnigmaApp.swift +52 -0
- package/apps/ios/EnigmaIOS/Enigma/Info.plist +52 -0
- package/apps/ios/EnigmaIOS/Enigma/NaturalLanguagePrivacyTagger.swift +26 -0
- package/apps/ios/EnigmaIOS/Enigma/OAuthClient.swift +321 -0
- package/apps/ios/EnigmaIOS/Enigma/OnboardingView.swift +105 -0
- package/apps/ios/EnigmaIOS/Enigma/PrivateVaultView.swift +275 -0
- package/apps/ios/EnigmaIOS/Enigma/SecureStore.swift +76 -0
- package/apps/ios/EnigmaIOS/Enigma/SettingsView.swift +60 -0
- package/apps/ios/EnigmaIOS/Enigma/Theme.swift +80 -0
- package/apps/ios/EnigmaIOS/EnigmaIOS.xcodeproj/project.pbxproj +211 -0
- package/apps/ios/EnigmaIOS/EnigmaIOS.xcodeproj/xcshareddata/xcschemes/Enigma.xcscheme +23 -0
- package/apps/native-host/README.md +19 -8
- package/apps/native-host/bin/enigma-native-host.mjs +229 -13
- package/apps/relay/bin/enigma-relay.mjs +103 -5
- package/apps/relay/src/federation-runtime.mjs +618 -0
- package/apps/relay/src/server.mjs +310 -9
- package/apps/verifier/bin/enigma-verify.mjs +327 -11
- package/cortex-v3/circuits/build/intent_vk_bytes.json +35 -0
- package/cortex-v3/circuits/build/sale_vk_bytes.json +35 -0
- package/cortex-v3/circuits/build/vk_bytes.json +32 -0
- package/cortex-v3/proving-assets.json +64 -0
- package/cortex-v3/zk/BUILD-CONTRACT.md +87 -0
- package/cortex-v3/zk/action-transition-vk.json +119 -0
- package/cortex-v3/zk/alias-adversarial.test.mjs +220 -0
- package/cortex-v3/zk/groth16-verify-child.mjs +17 -0
- package/cortex-v3/zk/intent-witness.mjs +365 -0
- package/cortex-v3/zk/intent-witness.test.mjs +485 -0
- package/cortex-v3/zk/proving-assets.mjs +203 -0
- package/cortex-v3/zk/sale-witness.mjs +783 -0
- package/cortex-v3/zk/sale-witness.test.mjs +784 -0
- package/cortex-v3/zk/sealed-sale-release-vk.json +119 -0
- package/cortex-v3/zk/settlement-evidence.mjs +722 -0
- package/cortex-v3/zk/setup-intent.mjs +688 -0
- package/cortex-v3/zk/setup-sale.mjs +666 -0
- package/cortex-v3/zk/setup.mjs +594 -0
- package/cortex-v3/zk/witness.mjs +184 -0
- package/cortex-v3/zk/zk-codec.mjs +232 -0
- package/cortex-v3/zk/zk-codec.test.mjs +293 -0
- package/cortex-v3/zk/zk-settle.mjs +370 -0
- package/cortex-v3/zk/zk-tree.mjs +256 -0
- package/cortex-v3/zk/zk-tree.test.mjs +419 -0
- package/deploy/docker-compose.local-production-simulation.yml +36 -0
- package/docs/browser-extension-install.md +8 -6
- package/docs/client-connectors.md +15 -11
- package/docs/developer-ecosystem.md +15 -13
- package/docs/enigma-memory-ready-conformance.md +11 -9
- package/docs/install-anywhere.md +61 -28
- package/docs/installers-and-desktop.md +8 -7
- package/docs/novelty-invention-candidates.md +161 -161
- package/docs/proof-network-claim-boundaries.md +320 -318
- package/examples/01-quickstart-agent/index.mjs +49 -0
- package/examples/01_agent_memory_quickstart.mjs +57 -0
- package/examples/02-multi-agent-swarm/index.mjs +57 -0
- package/examples/02_cross_model_passport.mjs +64 -0
- package/examples/03-langchain-memory/index.mjs +41 -0
- package/examples/03_poseidon_commitment_verification.mjs +71 -0
- package/examples/04-python-trading-agent/trader.py +49 -0
- package/examples/README.md +27 -0
- package/examples/ci/github-actions.yml +7 -2
- package/package.json +142 -11
- package/packages/adapters/PACKAGE_CONTRACT.md +1 -1
- package/packages/connectors/src/index.js +196 -4
- package/packages/connectors/swarm-router.mjs +168 -0
- package/packages/core/src/index.js +248 -1
- package/packages/core/src/version.mjs +7 -0
- package/packages/dev-tools/package.json +19 -0
- package/packages/dev-tools/src/index.js +4 -0
- package/packages/dev-tools/src/memory-benchmark-suite.js +112 -0
- package/packages/dev-tools/src/swarm-simulator.js +101 -0
- package/packages/dev-tools/src/vault-inspector.js +114 -0
- package/packages/dev-tools/src/vector-benchmark.js +100 -0
- package/packages/developer-platform/src/access-credentials.js +341 -0
- package/packages/developer-platform/src/http.js +132 -0
- package/packages/developer-platform/src/index.js +4 -0
- package/packages/developer-platform/src/usage-http.js +60 -0
- package/packages/developer-platform/src/usage.js +295 -0
- package/packages/enclave-runtime/attestation.mjs +159 -0
- package/packages/enclave-runtime/index.mjs +47 -0
- package/packages/enclave-runtime/session-manager.mjs +253 -0
- package/packages/enclave-runtime/zeroization-proof.mjs +227 -0
- package/packages/enigma-reflex/package.json +14 -0
- package/packages/enigma-reflex/src/index.js +204 -0
- package/packages/enigma-reflex/training/generate-dataset.mjs +40 -0
- package/packages/enigma-reflex/training/requirements.txt +8 -0
- package/packages/enigma-reflex/training/train.py +314 -0
- package/packages/enigma-weave/LICENSE +22 -0
- package/packages/enigma-weave/UPSTREAM.json +21 -0
- package/packages/enigma-weave/package.json +14 -0
- package/packages/enigma-weave/src/index.js +286 -0
- package/packages/hosted-cloud/src/index.js +80 -5
- package/packages/importers/src/index.js +432 -0
- package/packages/inference-runtime/src/browser.js +401 -0
- package/packages/inference-runtime/src/chat.js +265 -0
- package/packages/inference-runtime/src/code.js +407 -0
- package/packages/inference-runtime/src/contracts.js +162 -0
- package/packages/inference-runtime/src/http.js +232 -0
- package/packages/inference-runtime/src/image.js +186 -0
- package/packages/inference-runtime/src/index.js +10 -0
- package/packages/inference-runtime/src/model-router.js +320 -0
- package/packages/inference-runtime/src/platform.js +125 -0
- package/packages/inference-runtime/src/privacy.js +400 -0
- package/packages/inference-runtime/src/video.js +253 -0
- package/packages/mcp-server/README.md +22 -6
- package/packages/mcp-server/bin/enigma-mcp.mjs +2 -1
- package/packages/mcp-server/src/index.js +1418 -105
- package/packages/mcp-server/src/oauth.js +561 -0
- package/packages/mcp-server/src/private-handoff.js +84 -0
- package/packages/mcp-server/src/remote-http.js +273 -0
- package/packages/mcp-server/src/remote-policy.js +72 -0
- package/packages/mcp-server/swarm-bridge.mjs +361 -0
- package/packages/mesh/index.d.ts +283 -0
- package/packages/mesh/package.json +23 -0
- package/packages/mesh/src/crypto.js +189 -0
- package/packages/mesh/src/federation-packets.js +353 -0
- package/packages/mesh/src/gossip.js +311 -0
- package/packages/mesh/src/index.js +6 -0
- package/packages/mesh/src/protocol.js +255 -0
- package/packages/mesh/src/router.js +279 -0
- package/packages/mesh/src/transport.js +306 -0
- package/packages/passport/src/index.js +426 -1
- package/packages/private-economy/src/credits-http.js +100 -0
- package/packages/private-economy/src/credits.js +447 -0
- package/packages/private-economy/src/index.js +5 -0
- package/packages/private-economy/src/payments-http.js +120 -0
- package/packages/private-economy/src/payments.js +509 -0
- package/packages/private-economy/src/x402.js +346 -0
- package/packages/proof-network/PACKAGE_CONTRACT.md +21 -0
- package/packages/rag/index.d.ts +182 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/THIRD_PARTY_LICENSES.txt +207 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/config.json +25 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/onnx/model_quantized.onnx +0 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/sha256-manifest.json +28 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/tokenizer.json +30686 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/tokenizer_config.json +15 -0
- package/packages/rag/package.json +27 -0
- package/packages/rag/src/blinded-search.js +109 -0
- package/packages/rag/src/bm25.js +169 -0
- package/packages/rag/src/embeddings.js +459 -0
- package/packages/rag/src/hybrid.js +76 -0
- package/packages/rag/src/index.js +38 -0
- package/packages/rag/src/reranker.js +61 -0
- package/packages/rag/src/research.js +107 -0
- package/packages/rag/src/vector-store.js +430 -0
- package/packages/rag/src/verify-model-artifacts.mjs +4 -0
- package/packages/sdk/index.d.ts +760 -0
- package/packages/sdk/package.json +33 -0
- package/packages/sdk/python/README.md +24 -0
- package/packages/sdk/python/enigma_sdk.py +250 -0
- package/packages/sdk/python/pyproject.toml +34 -0
- package/packages/sdk/python/requirements.txt +1 -0
- package/packages/sdk/python/setup.py +20 -0
- package/packages/sdk/src/federation/capability-grant.js +389 -0
- package/packages/sdk/src/federation/federation-router.js +360 -0
- package/packages/sdk/src/federation/ghostmesh-bridge.js +497 -0
- package/packages/sdk/src/federation/index.js +3 -0
- package/packages/sdk/src/index.js +1796 -0
- package/packages/sdk/src/intelligence/contradiction.js +337 -0
- package/packages/sdk/src/intelligence/decision-engine.js +155 -0
- package/packages/sdk/src/intelligence/index.js +4 -0
- package/packages/sdk/src/intelligence/ontology.js +122 -0
- package/packages/sdk/src/intelligence/temporal.js +123 -0
- package/packages/sdk/src/market-client.js +142 -0
- package/packages/sdk/src/mesh-client.js +110 -0
- package/packages/sdk/src/middleware/index.js +3 -0
- package/packages/sdk/src/middleware/langchain.js +159 -0
- package/packages/sdk/src/middleware/llamaindex.js +101 -0
- package/packages/sdk/src/middleware/vercel-ai.js +112 -0
- package/packages/sdk/src/rag-client.js +85 -0
- package/packages/sdk/src/swarm-orchestrator.js +260 -0
- package/packages/settlement/PACKAGE_CONTRACT.md +1 -1
- package/packages/snapcompact/THIRD_PARTY_LICENSES.txt +40 -0
- package/packages/snapcompact/assets/8x13-latin1.bdf +3837 -0
- package/packages/snapcompact/index.d.ts +284 -0
- package/packages/snapcompact/package.json +25 -0
- package/packages/snapcompact/src/index.js +716 -0
- package/packages/storage/PACKAGE_CONTRACT.md +1 -1
- package/packages/terminal-console/animations.mjs +240 -0
- package/packages/terminal-console/auto-anchor.mjs +220 -0
- package/packages/terminal-console/banner.mjs +91 -0
- package/packages/terminal-console/commands.mjs +459 -0
- package/packages/terminal-console/delegation.mjs +152 -0
- package/packages/terminal-console/index.mjs +5 -0
- package/packages/terminal-console/outbox.mjs +143 -0
- package/packages/terminal-console/phantom-bridge.mjs +637 -0
- package/packages/terminal-console/repl.mjs +136 -0
- package/packages/terminal-console/signer-store.mjs +130 -0
- package/packages/terminal-console/solana-rpc.mjs +214 -0
- package/packages/terminal-console/solana-transport.mjs +189 -0
- package/packages/terminal-tui/dashboard.mjs +214 -0
- package/packages/terminal-tui/index.mjs +28 -0
- package/packages/terminal-tui/merkle-tree-renderer.mjs +268 -0
- package/packages/terminal-tui/telemetry-hud.mjs +137 -0
- package/packages/vault/index.d.ts +449 -0
- package/packages/vault/package.json +27 -0
- package/packages/vault/src/e2ee.mjs +393 -0
- package/packages/vault/src/enclave.js +481 -0
- package/packages/vault/src/erasure.js +207 -0
- package/packages/vault/src/index.js +1018 -155
- package/packages/vault/src/persistence.js +307 -0
- package/packages/vault/src/poseidon.js +354 -0
- package/packages/vault/src/receipt.js +459 -0
- package/scripts/benchmark-optical-context.mjs +166 -0
- package/scripts/bootstrap-enigma.mjs +502 -0
- package/scripts/build-edge-backend-workers.mjs +20 -5
- package/scripts/build-goal-completion-audit.mjs +72 -25
- package/scripts/build-hosted-api-key-lifecycle.mjs +26 -8
- package/scripts/build-hosted-customer-lifecycle.mjs +20 -3
- package/scripts/build-hosted-probe-worker.mjs +19 -4
- package/scripts/build-installer-assets.mjs +41 -21
- package/scripts/build-operator-evidence-starter.mjs +59 -1
- package/scripts/build-production-backend-env-kit.mjs +2 -0
- package/scripts/build-production-unblocker.mjs +3 -0
- package/scripts/check.mjs +17 -3
- package/scripts/collect-hosted-backend-live-evidence.mjs +49 -12
- package/scripts/install-enigma-local.mjs +18 -5
- package/scripts/release-audit.mjs +65 -109
- package/scripts/release-provenance.mjs +6 -0
- package/scripts/run-backend-readiness-smoke.mjs +112 -10
- package/scripts/scan-secrets.mjs +1 -0
- package/scripts/simulate-production-env.mjs +7 -2
- package/scripts/validate-hosted-backend-live.mjs +112 -1
- package/specs/antibody-pack-v1.schema.json +95 -0
- package/specs/antigen-envelope-v1.schema.json +81 -0
- package/specs/boundary-manifest-v1.schema.json +35 -35
- package/specs/capsule-v1.schema.json +55 -55
- package/specs/claim-boundary-manifest-v1.schema.json +22 -22
- package/specs/claim-ledger-v1.schema.json +291 -0
- package/specs/context-passport-v1.schema.json +59 -0
- package/specs/deletion-tombstone-v1.schema.json +26 -26
- package/specs/evidence-packet-v1.schema.json +177 -0
- package/specs/hosted-backend-live-evidence-v1.schema.json +72 -3
- package/specs/immune-scan-report-v1.schema.json +112 -0
- package/specs/lifecycle-receipt-log-v1.schema.json +67 -0
- package/specs/memory-atom-v1.schema.json +59 -0
- package/specs/memory-event-v1.schema.json +42 -42
- package/specs/passport-v1.schema.json +50 -50
- package/specs/proof-of-non-use-v1.schema.json +65 -0
- package/specs/quarantine-record-v1.schema.json +126 -0
- package/specs/receipt-v1.schema.json +61 -61
- package/specs/state-checkpoint-v1.schema.json +37 -37
- package/specs/trust-bundle-v1.schema.json +56 -56
- package/specs/trust-card-v1.schema.json +119 -0
- package/docs/proof-network-launch-plan.md +0 -421
- package/packages/metering/PACKAGE_CONTRACT.md +0 -20
- package/scripts/build-ai-orchestration-plan.mjs +0 -248
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { realpathSync } from 'node:fs';
|
|
2
|
+
import { existsSync, realpathSync } from 'node:fs';
|
|
3
|
+
import { once } from 'node:events';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
3
5
|
import { pathToFileURL } from 'node:url';
|
|
4
6
|
import { DEFAULT_GATEWAY_PORT, main as cliMain } from '../../cli/bin/enigma.mjs';
|
|
7
|
+
import {
|
|
8
|
+
createGatewayServer,
|
|
9
|
+
createGatewayState,
|
|
10
|
+
loadGatewayStateFromFile,
|
|
11
|
+
saveGatewayStateToFile,
|
|
12
|
+
} from '../src/server.mjs';
|
|
5
13
|
|
|
6
14
|
function gatewayUsage() {
|
|
7
15
|
return {
|
|
@@ -21,21 +29,110 @@ function gatewayUsage() {
|
|
|
21
29
|
function print(value, io) {
|
|
22
30
|
io.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
|
|
23
31
|
}
|
|
32
|
+
function publicStartError(error) {
|
|
33
|
+
const message = error instanceof Error ? error.message : String(error ?? '');
|
|
34
|
+
if (/state schema mismatch/i.test(message)) return 'gateway state schema mismatch';
|
|
35
|
+
if (/requires (?:a |an )?[A-Za-z0-9 _/-]+(?:adapter|ref|value)/i.test(message) && !/[\\:]|Bearer|token|secret/i.test(message)) {
|
|
36
|
+
return message.slice(0, 240);
|
|
37
|
+
}
|
|
38
|
+
return 'gateway failed to start; inspect local operator logs';
|
|
39
|
+
}
|
|
40
|
+
|
|
24
41
|
|
|
25
42
|
function isHelp(argv) {
|
|
26
43
|
return argv.includes('--help') || argv.includes('-h');
|
|
27
44
|
}
|
|
28
45
|
|
|
29
|
-
function
|
|
30
|
-
|
|
46
|
+
function parseServeArgs(argv) {
|
|
47
|
+
const args = argv[0] === 'serve' ? argv.slice(1) : argv;
|
|
48
|
+
const parsed = { host: '127.0.0.1', port: DEFAULT_GATEWAY_PORT, once: false, stateFile: null };
|
|
49
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
50
|
+
const argument = args[index];
|
|
51
|
+
if (argument === '--once') {
|
|
52
|
+
parsed.once = true;
|
|
53
|
+
} else if (argument === '--host' || argument === '--port' || argument === '--state-file') {
|
|
54
|
+
const value = args[++index];
|
|
55
|
+
if (!value) throw new TypeError(`${argument} requires a value`);
|
|
56
|
+
if (argument === '--host') parsed.host = value;
|
|
57
|
+
if (argument === '--state-file') parsed.stateFile = value;
|
|
58
|
+
if (argument === '--port') {
|
|
59
|
+
parsed.port = Number(value);
|
|
60
|
+
if (!Number.isSafeInteger(parsed.port) || parsed.port < 0 || parsed.port > 65535) {
|
|
61
|
+
throw new TypeError('--port must be an integer between 0 and 65535');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
throw new TypeError(`unknown gateway serve option: ${argument}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return parsed;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function loadServeModuleOptions(env) {
|
|
72
|
+
const moduleRef = env.ENIGMA_GATEWAY_SERVE_MODULE ?? env.ENIGMA_FEDERATION_SERVE_MODULE;
|
|
73
|
+
if (!moduleRef) return {};
|
|
74
|
+
const moduleUrl = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(moduleRef)
|
|
75
|
+
? moduleRef
|
|
76
|
+
: pathToFileURL(resolve(moduleRef)).href;
|
|
77
|
+
const loaded = await import(moduleUrl);
|
|
78
|
+
const factory = loaded.createGatewayServeOptions ?? loaded.createServeOptions ?? loaded.default;
|
|
79
|
+
if (typeof factory !== 'function') {
|
|
80
|
+
throw new TypeError('gateway serve module must export createGatewayServeOptions(), createServeOptions(), or a default factory');
|
|
81
|
+
}
|
|
82
|
+
const options = await factory({ service: 'gateway', env: { ...env } });
|
|
83
|
+
if (!options || typeof options !== 'object' || Array.isArray(options)) {
|
|
84
|
+
throw new TypeError('gateway serve module factory must return an options object');
|
|
85
|
+
}
|
|
86
|
+
return options;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function runServe(argv, io, env) {
|
|
90
|
+
const flags = parseServeArgs(argv);
|
|
91
|
+
const moduleOptions = await loadServeModuleOptions(env);
|
|
92
|
+
const stateOptions = {
|
|
93
|
+
...moduleOptions,
|
|
94
|
+
mode: moduleOptions.mode ?? env.ENIGMA_DEPLOYMENT_MODE ?? env.ENIGMA_MODE ?? env.NODE_ENV ?? 'local',
|
|
95
|
+
};
|
|
96
|
+
const state = moduleOptions.state ?? (
|
|
97
|
+
flags.stateFile && existsSync(flags.stateFile)
|
|
98
|
+
? loadGatewayStateFromFile(flags.stateFile, stateOptions)
|
|
99
|
+
: createGatewayState(stateOptions)
|
|
100
|
+
);
|
|
101
|
+
const server = createGatewayServer({ ...stateOptions, state, stateFile: flags.stateFile });
|
|
102
|
+
server.listen(flags.port, flags.host);
|
|
103
|
+
await once(server, 'listening');
|
|
104
|
+
const address = server.address();
|
|
105
|
+
print({
|
|
106
|
+
ok: true,
|
|
107
|
+
service: 'enigma-gateway',
|
|
108
|
+
mode: state.mode,
|
|
109
|
+
address: typeof address === 'object' && address ? { host: address.address, port: address.port } : address,
|
|
110
|
+
federation: server.federationRuntime?.status() ?? { enabled: false },
|
|
111
|
+
}, io);
|
|
112
|
+
if (flags.stateFile) saveGatewayStateToFile(server.gatewayState, flags.stateFile);
|
|
113
|
+
if (flags.once) {
|
|
114
|
+
server.close();
|
|
115
|
+
await once(server, 'close');
|
|
116
|
+
}
|
|
117
|
+
return 0;
|
|
31
118
|
}
|
|
32
119
|
|
|
33
|
-
export async function main(
|
|
120
|
+
export async function main(
|
|
121
|
+
argv = process.argv.slice(2),
|
|
122
|
+
io = { stdout: process.stdout, stderr: process.stderr },
|
|
123
|
+
env = process.env
|
|
124
|
+
) {
|
|
34
125
|
if (isHelp(argv)) {
|
|
35
126
|
print(gatewayUsage(), io);
|
|
36
127
|
return 0;
|
|
37
128
|
}
|
|
38
|
-
return cliMain(
|
|
129
|
+
if (argv[0] === 'demo') return cliMain(['gateway', ...argv], io);
|
|
130
|
+
try {
|
|
131
|
+
return await runServe(argv, io, env);
|
|
132
|
+
} catch (error) {
|
|
133
|
+
print({ ok: false, error: { code: 'GATEWAY_START_FAILED', message: publicStartError(error) } }, io);
|
|
134
|
+
return 2;
|
|
135
|
+
}
|
|
39
136
|
}
|
|
40
137
|
function isMainModule(metaUrl) {
|
|
41
138
|
if (!process.argv[1]) return false;
|
|
@@ -14,10 +14,14 @@ import {
|
|
|
14
14
|
normalizeDependencyEvidence,
|
|
15
15
|
readinessEvidenceRefs,
|
|
16
16
|
} from '../../../packages/adapters/src/index.js';
|
|
17
|
+
import { attachFederationServeMode } from '../../relay/src/federation-runtime.mjs';
|
|
17
18
|
|
|
18
19
|
const GATEWAY_REQUEST_SCHEMA = 'enigma.gateway_request.v1';
|
|
19
20
|
const GATEWAY_EXPORT_SCHEMA = 'enigma.gateway_siem_export.v1';
|
|
20
21
|
const GATEWAY_STATE_SCHEMA = 'enigma.gateway_state.v1';
|
|
22
|
+
export const GATEWAY_STATE_ADAPTER_SCHEMA = 'enigma.gateway_state_adapter.v1';
|
|
23
|
+
export const GATEWAY_KMS_SIGNER_ADAPTER_SCHEMA = 'enigma.gateway_kms_signer_adapter.v1';
|
|
24
|
+
export const GATEWAY_SIEM_SINK_ADAPTER_SCHEMA = 'enigma.gateway_siem_sink_adapter.v1';
|
|
21
25
|
const GATEWAY_STATE_VERSION = 1;
|
|
22
26
|
const DEFAULT_GATEWAY_ID = 'gateway_local';
|
|
23
27
|
const DEFAULT_ACTIVE_ROOT = `sha256:${sha256Hex('enigma.gateway.empty_active_root.v1')}`;
|
|
@@ -287,6 +291,27 @@ function createDecisionForRequest(state, request, evaluation) {
|
|
|
287
291
|
});
|
|
288
292
|
return redactAndResignDecision(decision, state);
|
|
289
293
|
}
|
|
294
|
+
async function createRuntimeDecisionForRequest(state, request, evaluation) {
|
|
295
|
+
const signer = state.gatewayProductionRuntime?.kmsSigner;
|
|
296
|
+
if (!signer) return createDecisionForRequest(state, request, evaluation);
|
|
297
|
+
const decision = await signer.createDecision({
|
|
298
|
+
policy: state.policy,
|
|
299
|
+
request,
|
|
300
|
+
evaluation,
|
|
301
|
+
gateway_id: state.gateway_id,
|
|
302
|
+
active_root: state.active_root,
|
|
303
|
+
});
|
|
304
|
+
if (!isPlainRecord(decision) || containsPlaintextMemory(decision)) {
|
|
305
|
+
throw new Error('KMS signer returned an invalid gateway decision');
|
|
306
|
+
}
|
|
307
|
+
const verification = verifyGatewayDecision({
|
|
308
|
+
decision,
|
|
309
|
+
policy: state.policy,
|
|
310
|
+
publicKey: signer.publicKey,
|
|
311
|
+
});
|
|
312
|
+
if (verification.ok !== true) throw new Error('KMS signer returned an unverifiable gateway decision');
|
|
313
|
+
return decision;
|
|
314
|
+
}
|
|
290
315
|
|
|
291
316
|
|
|
292
317
|
function publicGatewayEvaluation(state, evaluation) {
|
|
@@ -438,6 +463,7 @@ export function hydrateGatewayState(snapshot, options = {}) {
|
|
|
438
463
|
const parsed = typeof snapshot === 'string' ? JSON.parse(snapshot) : snapshot;
|
|
439
464
|
validateGatewayStateSnapshot(parsed);
|
|
440
465
|
return createGatewayState({
|
|
466
|
+
...options,
|
|
441
467
|
gateway_id: parsed.gateway_id,
|
|
442
468
|
active_root: parsed.active_root,
|
|
443
469
|
policy: parsed.policy,
|
|
@@ -809,7 +835,7 @@ function gatewayProductionReadinessFromOptions(options) {
|
|
|
809
835
|
options.persistence,
|
|
810
836
|
options.persistence_backend,
|
|
811
837
|
options.persistenceBackend,
|
|
812
|
-
envValue('ENIGMA_EXTERNAL_STORAGE_DSN', '
|
|
838
|
+
envValue('ENIGMA_EXTERNAL_STORAGE_DSN', 'ENIGMA_EXTERNAL_STORAGE_REF', 'ENIGMA_GATEWAY_STORAGE_REF', 'ENIGMA_DURABLE_STORAGE_REF', 'ENIGMA_GATEWAY_STATE_BACKEND')
|
|
813
839
|
),
|
|
814
840
|
kms_or_secret_custody: firstDefined(
|
|
815
841
|
options.kms_or_secret_custody,
|
|
@@ -835,7 +861,7 @@ function gatewayProductionReadinessFromOptions(options) {
|
|
|
835
861
|
options.auditSink,
|
|
836
862
|
options.log_sink,
|
|
837
863
|
options.logSink,
|
|
838
|
-
envValue('ENIGMA_SIEM_EXPORT_ENDPOINT', '
|
|
864
|
+
envValue('ENIGMA_SIEM_EXPORT_ENDPOINT', 'ENIGMA_SIEM_REF', 'ENIGMA_AUDIT_SINK_REF', 'ENIGMA_LOG_SINK_REF')
|
|
839
865
|
),
|
|
840
866
|
backup_restore: firstDefined(
|
|
841
867
|
options.backup_restore,
|
|
@@ -845,7 +871,7 @@ function gatewayProductionReadinessFromOptions(options) {
|
|
|
845
871
|
options.backupTarget,
|
|
846
872
|
options.restore_target,
|
|
847
873
|
options.restoreTarget,
|
|
848
|
-
envValue('ENIGMA_BACKUP_TARGET_URI', '
|
|
874
|
+
envValue('ENIGMA_BACKUP_TARGET_URI', 'ENIGMA_BACKUP_TARGET_REF', 'ENIGMA_RESTORE_TARGET_REF')
|
|
849
875
|
),
|
|
850
876
|
monitoring: firstDefined(
|
|
851
877
|
options.monitoring,
|
|
@@ -1179,6 +1205,8 @@ function gatewayReadiness(state) {
|
|
|
1179
1205
|
readinessValue(state, 'data_plane_auth', 'dataPlaneAuth', 'data_plane_auth_ref', 'dataPlaneAuthRef'),
|
|
1180
1206
|
readinessValue(state, 'data_plane_auth_configured')
|
|
1181
1207
|
));
|
|
1208
|
+
const adminAuthHash = gatewayAuthHash(state, 'admin');
|
|
1209
|
+
const dataPlaneAuthHash = gatewayAuthHash(state, 'data_plane');
|
|
1182
1210
|
const operatorAccepted = operatorAcceptanceIsGo(firstDefined(
|
|
1183
1211
|
readinessValue(state, 'operator_acceptance', 'operatorAcceptance', 'acceptance', 'go_live', 'goLive'),
|
|
1184
1212
|
readinessValue(state, 'operator_acceptance')
|
|
@@ -1192,6 +1220,8 @@ function gatewayReadiness(state) {
|
|
|
1192
1220
|
gatewayReadinessCheck('state_not_local_in_memory', !gatewayStateIsLocalOnly(state, durableStorage), 'gateway production state is local/in-memory only'),
|
|
1193
1221
|
gatewayReadinessCheck('admin_auth', adminAuth, 'admin authentication is not configured'),
|
|
1194
1222
|
gatewayReadinessCheck('data_plane_auth', dataPlaneAuth, 'data-plane authentication is not configured'),
|
|
1223
|
+
gatewayReadinessCheck('admin_auth_bearer_hash', Boolean(adminAuthHash), 'production admin authentication bearer hash is invalid or missing'),
|
|
1224
|
+
gatewayReadinessCheck('data_plane_auth_bearer_hash', Boolean(dataPlaneAuthHash), 'production data-plane authentication bearer hash is invalid or missing'),
|
|
1195
1225
|
gatewayReadinessCheck('durable_storage', durableStorage, 'production durable storage is not configured'),
|
|
1196
1226
|
gatewayReadinessCheck('kms_or_signer_ref', kmsOrSigner, 'production KMS/signer reference is not configured'),
|
|
1197
1227
|
gatewayReadinessCheck('siem_or_audit_sink', siemOrAudit, 'production SIEM/audit routing is not configured'),
|
|
@@ -1204,6 +1234,22 @@ function gatewayReadiness(state) {
|
|
|
1204
1234
|
: [
|
|
1205
1235
|
gatewayReadinessCheck('non_production_local_mode', isLocalReadinessMode(state), 'gateway readiness is only green for non-production local mode')
|
|
1206
1236
|
];
|
|
1237
|
+
const federationStatus = state.federationRuntime?.status();
|
|
1238
|
+
if (federationStatus) {
|
|
1239
|
+
checks.push(...federationStatus.checks.map((check) => gatewayReadinessCheck(
|
|
1240
|
+
check.check,
|
|
1241
|
+
check.ok,
|
|
1242
|
+
`${check.check.replaceAll('_', ' ')} is not ready`
|
|
1243
|
+
)));
|
|
1244
|
+
}
|
|
1245
|
+
const productionRuntimeStatus = state.gatewayProductionRuntime?.status();
|
|
1246
|
+
if (productionRuntimeStatus) {
|
|
1247
|
+
checks.push(...productionRuntimeStatus.checks.map((check) => gatewayReadinessCheck(
|
|
1248
|
+
check.check,
|
|
1249
|
+
check.ok,
|
|
1250
|
+
`${check.check.replaceAll('_', ' ')} is not ready`
|
|
1251
|
+
)));
|
|
1252
|
+
}
|
|
1207
1253
|
const missingChecks = checks.filter((check) => check.ok !== true).map((check) => check.check);
|
|
1208
1254
|
const ready = checks.every((check) => check.ok === true);
|
|
1209
1255
|
return {
|
|
@@ -1234,6 +1280,7 @@ export async function handleGatewayRequest(state, request, response = undefined)
|
|
|
1234
1280
|
gateway_id: state.gateway_id,
|
|
1235
1281
|
policy_id: state.policy.policy_id,
|
|
1236
1282
|
policy_hash: state.policy.policy_hash,
|
|
1283
|
+
federation: state.federationRuntime?.status() ?? { enabled: false, ready: false },
|
|
1237
1284
|
}, response);
|
|
1238
1285
|
}
|
|
1239
1286
|
|
|
@@ -1247,6 +1294,7 @@ export async function handleGatewayRequest(state, request, response = undefined)
|
|
|
1247
1294
|
}
|
|
1248
1295
|
|
|
1249
1296
|
if (method === 'GET' && path === '/readyz') {
|
|
1297
|
+
if (state.federationRuntime) await state.federationRuntime.refreshDependencies();
|
|
1250
1298
|
const readiness = gatewayReadiness(state);
|
|
1251
1299
|
return gatewayResponse(readiness.statusCode, readiness.body, response);
|
|
1252
1300
|
}
|
|
@@ -1292,8 +1340,12 @@ export async function handleGatewayRequest(state, request, response = undefined)
|
|
|
1292
1340
|
return gatewayResponse(normalized.status, { ok: false, error: { code: 'REQUEST_INVALID', reason_codes: normalized.errors } }, response);
|
|
1293
1341
|
}
|
|
1294
1342
|
const evaluation = evaluateEnterprisePolicy(state.policy, normalized.request);
|
|
1295
|
-
const decision =
|
|
1296
|
-
const verification = verifyGatewayDecision({
|
|
1343
|
+
const decision = await createRuntimeDecisionForRequest(state, normalized.request, evaluation);
|
|
1344
|
+
const verification = verifyGatewayDecision({
|
|
1345
|
+
decision,
|
|
1346
|
+
policy: state.policy,
|
|
1347
|
+
publicKey: state.gatewayProductionRuntime?.kmsSigner.publicKey ?? state.signingKeyPair.publicKey
|
|
1348
|
+
});
|
|
1297
1349
|
const siem_event = siemEventForDecision(state, decision);
|
|
1298
1350
|
return gatewayResponse(200, { ok: true, evaluation: publicGatewayEvaluation(state, evaluation), decision, verification, siem_event }, response);
|
|
1299
1351
|
}
|
|
@@ -1318,12 +1370,223 @@ export async function handleGatewayRequest(state, request, response = undefined)
|
|
|
1318
1370
|
}
|
|
1319
1371
|
}
|
|
1320
1372
|
|
|
1373
|
+
function gatewayFederationOptions(options, state) {
|
|
1374
|
+
const configured = options.federation ?? options.federationServe;
|
|
1375
|
+
if (!configured) return null;
|
|
1376
|
+
const readiness = state.production_readiness ?? {};
|
|
1377
|
+
return {
|
|
1378
|
+
...configured,
|
|
1379
|
+
mode: configured.mode ?? state.mode,
|
|
1380
|
+
authRef: configured.authRef ?? readiness.data_plane_auth,
|
|
1381
|
+
kmsRef: configured.kmsRef ?? readiness.kms_or_secret_custody,
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
function gatewayReplicaCount(options) {
|
|
1386
|
+
const value = firstDefined(
|
|
1387
|
+
options.replicaCount,
|
|
1388
|
+
options.replica_count,
|
|
1389
|
+
envValue('ENIGMA_GATEWAY_REPLICA_COUNT', 'ENIGMA_REPLICA_COUNT')
|
|
1390
|
+
);
|
|
1391
|
+
if (value === undefined) return 1;
|
|
1392
|
+
const count = Number(value);
|
|
1393
|
+
if (!Number.isSafeInteger(count) || count < 1) throw new TypeError('gateway replica count must be a positive safe integer');
|
|
1394
|
+
return count;
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
function validateGatewayProductionAdapter(adapter, schema, methods, label) {
|
|
1398
|
+
if (!isPlainRecord(adapter) || adapter.schema !== schema || !nonEmptyString(adapter.ref)) {
|
|
1399
|
+
throw new TypeError(`${label} must implement ${schema} with a durable external ref`);
|
|
1400
|
+
}
|
|
1401
|
+
for (const method of methods) {
|
|
1402
|
+
if (typeof adapter[method] !== 'function') throw new TypeError(`${label} must implement ${method}()`);
|
|
1403
|
+
}
|
|
1404
|
+
return adapter;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
class GatewayProductionRuntime {
|
|
1408
|
+
constructor(options, initialState, replicaCount) {
|
|
1409
|
+
this.stateAdapter = validateGatewayProductionAdapter(
|
|
1410
|
+
options.gatewayStateAdapter ?? options.gateway_state_adapter,
|
|
1411
|
+
GATEWAY_STATE_ADAPTER_SCHEMA,
|
|
1412
|
+
['isReady', 'transaction'],
|
|
1413
|
+
'gateway state adapter'
|
|
1414
|
+
);
|
|
1415
|
+
this.kmsSigner = validateGatewayProductionAdapter(
|
|
1416
|
+
options.kmsSignerAdapter ?? options.kms_signer_adapter,
|
|
1417
|
+
GATEWAY_KMS_SIGNER_ADAPTER_SCHEMA,
|
|
1418
|
+
['isReady', 'createDecision'],
|
|
1419
|
+
'gateway KMS signer adapter'
|
|
1420
|
+
);
|
|
1421
|
+
this.siemSink = validateGatewayProductionAdapter(
|
|
1422
|
+
options.siemSinkAdapter ?? options.siem_sink_adapter,
|
|
1423
|
+
GATEWAY_SIEM_SINK_ADAPTER_SCHEMA,
|
|
1424
|
+
['isReady', 'appendBatch'],
|
|
1425
|
+
'gateway SIEM sink adapter'
|
|
1426
|
+
);
|
|
1427
|
+
if (this.stateAdapter.durable !== true || this.stateAdapter.encryptedAtRest !== true) {
|
|
1428
|
+
throw new TypeError('production gateway state adapter must be durable and encrypted at rest');
|
|
1429
|
+
}
|
|
1430
|
+
if (replicaCount > 1 && this.stateAdapter.supportsMultiReplica !== true) {
|
|
1431
|
+
throw new TypeError('multiple gateway replicas require an atomic multi-replica state adapter');
|
|
1432
|
+
}
|
|
1433
|
+
if (this.siemSink.durable !== true || this.siemSink.idempotent !== true) {
|
|
1434
|
+
throw new TypeError('production gateway SIEM sink must be durable and idempotent');
|
|
1435
|
+
}
|
|
1436
|
+
if (!nonEmptyString(this.kmsSigner.publicKey)) {
|
|
1437
|
+
throw new TypeError('gateway KMS signer adapter publicKey is required');
|
|
1438
|
+
}
|
|
1439
|
+
this.options = options;
|
|
1440
|
+
this.replicaCount = replicaCount;
|
|
1441
|
+
this.state = initialState;
|
|
1442
|
+
this.initialSnapshot = serializeGatewayState(initialState);
|
|
1443
|
+
this.stateReady = false;
|
|
1444
|
+
this.signerReady = false;
|
|
1445
|
+
this.siemReady = false;
|
|
1446
|
+
this.lastError = null;
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
decorate(state, federationRuntime) {
|
|
1450
|
+
Object.defineProperties(state, {
|
|
1451
|
+
gatewayProductionRuntime: {
|
|
1452
|
+
value: this,
|
|
1453
|
+
writable: false,
|
|
1454
|
+
configurable: true
|
|
1455
|
+
},
|
|
1456
|
+
...(federationRuntime ? {
|
|
1457
|
+
federationRuntime: {
|
|
1458
|
+
value: federationRuntime,
|
|
1459
|
+
writable: false,
|
|
1460
|
+
configurable: true
|
|
1461
|
+
}
|
|
1462
|
+
} : {})
|
|
1463
|
+
});
|
|
1464
|
+
return state;
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
async refresh() {
|
|
1468
|
+
try {
|
|
1469
|
+
[this.stateReady, this.signerReady, this.siemReady] = await Promise.all([
|
|
1470
|
+
this.stateAdapter.isReady(),
|
|
1471
|
+
this.kmsSigner.isReady(),
|
|
1472
|
+
this.siemSink.isReady(),
|
|
1473
|
+
]);
|
|
1474
|
+
this.stateReady = this.stateReady === true;
|
|
1475
|
+
this.signerReady = this.signerReady === true;
|
|
1476
|
+
this.siemReady = this.siemReady === true;
|
|
1477
|
+
if (!this.stateReady || !this.signerReady || !this.siemReady) {
|
|
1478
|
+
throw new Error('one or more gateway production adapters are unavailable');
|
|
1479
|
+
}
|
|
1480
|
+
this.lastError = null;
|
|
1481
|
+
} catch (error) {
|
|
1482
|
+
this.stateReady = false;
|
|
1483
|
+
this.signerReady = false;
|
|
1484
|
+
this.siemReady = false;
|
|
1485
|
+
this.lastError = error instanceof Error ? error.message : 'gateway production dependency failed';
|
|
1486
|
+
}
|
|
1487
|
+
return this.stateReady && this.signerReady && this.siemReady;
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
status() {
|
|
1491
|
+
return {
|
|
1492
|
+
ready: this.stateReady && this.signerReady && this.siemReady,
|
|
1493
|
+
state_ref: this.stateAdapter.ref,
|
|
1494
|
+
signer_ref: this.kmsSigner.ref,
|
|
1495
|
+
siem_ref: this.siemSink.ref,
|
|
1496
|
+
replica_count: this.replicaCount,
|
|
1497
|
+
last_error: this.lastError,
|
|
1498
|
+
checks: [
|
|
1499
|
+
{ check: 'gateway_state_adapter', ok: this.stateReady },
|
|
1500
|
+
{ check: 'gateway_kms_signer', ok: this.signerReady },
|
|
1501
|
+
{ check: 'gateway_siem_sink', ok: this.siemReady },
|
|
1502
|
+
{ check: 'gateway_replica_safety', ok: this.replicaCount === 1 || this.stateAdapter.supportsMultiReplica === true },
|
|
1503
|
+
]
|
|
1504
|
+
};
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
async handle(request, response, federationRuntime) {
|
|
1508
|
+
const path = routePath(request);
|
|
1509
|
+
if (path === '/livez') {
|
|
1510
|
+
await handleGatewayRequest(this.decorate(this.state, federationRuntime), request, response);
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
const ready = await this.refresh();
|
|
1514
|
+
if (!ready && path !== '/readyz') {
|
|
1515
|
+
gatewayResponse(503, { ok: false, error: { code: 'GATEWAY_DEPENDENCY_UNAVAILABLE' } }, response);
|
|
1516
|
+
return;
|
|
1517
|
+
}
|
|
1518
|
+
if (!ready) {
|
|
1519
|
+
await handleGatewayRequest(this.decorate(this.state, federationRuntime), request, response);
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1522
|
+
try {
|
|
1523
|
+
const value = await this.stateAdapter.transaction(async (storedSnapshot) => {
|
|
1524
|
+
const state = this.decorate(
|
|
1525
|
+
storedSnapshot ? hydrateGatewayState(storedSnapshot, this.options) : hydrateGatewayState(this.initialSnapshot, this.options),
|
|
1526
|
+
federationRuntime
|
|
1527
|
+
);
|
|
1528
|
+
const priorEventCount = state.siem_events.length;
|
|
1529
|
+
const result = await handleGatewayRequest(state, request);
|
|
1530
|
+
const newEvents = state.siem_events.slice(priorEventCount);
|
|
1531
|
+
if (newEvents.length > 0) await this.siemSink.appendBatch(newEvents);
|
|
1532
|
+
return {
|
|
1533
|
+
snapshot: serializeGatewayState(state),
|
|
1534
|
+
value: { state, result }
|
|
1535
|
+
};
|
|
1536
|
+
}, { initialSnapshot: this.initialSnapshot });
|
|
1537
|
+
if (!value?.state || !value?.result) throw new Error('gateway state transaction returned an invalid result');
|
|
1538
|
+
this.state = value.state;
|
|
1539
|
+
gatewayResponse(value.result.status, value.result.body, response);
|
|
1540
|
+
} catch (error) {
|
|
1541
|
+
this.stateReady = false;
|
|
1542
|
+
this.lastError = error instanceof Error ? error.message : 'gateway state transaction failed';
|
|
1543
|
+
gatewayResponse(503, { ok: false, error: { code: 'GATEWAY_DURABLE_TRANSACTION_FAILED' } }, response);
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1321
1548
|
export function createGatewayServer(options = {}) {
|
|
1322
|
-
const
|
|
1549
|
+
const initialState = options.state ?? createGatewayState(options);
|
|
1550
|
+
const production = isProductionLikeState(initialState);
|
|
1551
|
+
const replicaCount = gatewayReplicaCount(options);
|
|
1552
|
+
let federationRuntime = null;
|
|
1553
|
+
const productionRuntime = production ? new GatewayProductionRuntime(options, initialState, replicaCount) : null;
|
|
1554
|
+
const localStateFile = !production && typeof options.stateFile === 'string' && options.stateFile
|
|
1555
|
+
? options.stateFile
|
|
1556
|
+
: null;
|
|
1323
1557
|
const server = createServer((request, response) => {
|
|
1324
|
-
|
|
1558
|
+
const task = productionRuntime
|
|
1559
|
+
? productionRuntime.handle(request, response, federationRuntime)
|
|
1560
|
+
: handleGatewayRequest(initialState, request, response);
|
|
1561
|
+
void task.then(() => {
|
|
1562
|
+
if (localStateFile) saveGatewayStateToFile(initialState, localStateFile);
|
|
1563
|
+
}).catch((error) => {
|
|
1564
|
+
server.emit('statePersistenceError', error);
|
|
1565
|
+
if (!response.headersSent) gatewayResponse(500, { ok: false, error: { code: 'GATEWAY_ERROR' } }, response);
|
|
1566
|
+
});
|
|
1567
|
+
});
|
|
1568
|
+
const federationOptions = gatewayFederationOptions(options, initialState);
|
|
1569
|
+
if (production && !federationOptions) {
|
|
1570
|
+
throw new TypeError('production gateway serve mode requires federation forwarding configuration');
|
|
1571
|
+
}
|
|
1572
|
+
if (federationOptions) {
|
|
1573
|
+
federationRuntime = attachFederationServeMode(server, federationOptions);
|
|
1574
|
+
Object.defineProperty(initialState, 'federationRuntime', {
|
|
1575
|
+
value: federationRuntime,
|
|
1576
|
+
writable: false,
|
|
1577
|
+
configurable: true,
|
|
1578
|
+
});
|
|
1579
|
+
server.federationRuntime = federationRuntime;
|
|
1580
|
+
}
|
|
1581
|
+
if (productionRuntime) {
|
|
1582
|
+
productionRuntime.decorate(initialState, federationRuntime);
|
|
1583
|
+
server.gatewayProductionRuntime = productionRuntime;
|
|
1584
|
+
server.once('listening', () => void productionRuntime.refresh());
|
|
1585
|
+
}
|
|
1586
|
+
Object.defineProperty(server, 'gatewayState', {
|
|
1587
|
+
configurable: true,
|
|
1588
|
+
get: () => productionRuntime?.state ?? initialState,
|
|
1325
1589
|
});
|
|
1326
|
-
server.gatewayState = state;
|
|
1327
1590
|
return server;
|
|
1328
1591
|
}
|
|
1329
1592
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// swift-tools-version: 6.0
|
|
2
|
+
import PackageDescription
|
|
3
|
+
|
|
4
|
+
let package = Package(
|
|
5
|
+
name: "EnigmaCore",
|
|
6
|
+
platforms: [.iOS(.v17), .macOS(.v14)],
|
|
7
|
+
products: [.library(name: "EnigmaCore", targets: ["EnigmaCore"])],
|
|
8
|
+
targets: [
|
|
9
|
+
.target(name: "EnigmaCore"),
|
|
10
|
+
.testTarget(name: "EnigmaCoreTests", dependencies: ["EnigmaCore"]),
|
|
11
|
+
]
|
|
12
|
+
)
|