@nextera.one/axis-server-sdk 2.3.12 → 2.3.14
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/dist/{index-D_6djkZB.d.ts → index-B0HcQRif.d.ts} +5 -4
- package/dist/{index-DZdmfbDZ.d.mts → index-C5NXMEth.d.mts} +5 -4
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +294 -220
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +294 -221
- package/dist/index.mjs.map +1 -1
- package/dist/sensors/index.d.mts +1 -1
- package/dist/sensors/index.d.ts +1 -1
- package/dist/sensors/index.js +294 -220
- package/dist/sensors/index.js.map +1 -1
- package/dist/sensors/index.mjs +294 -221
- package/dist/sensors/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2364,21 +2364,71 @@ var init_axis_error = __esm({
|
|
|
2364
2364
|
}
|
|
2365
2365
|
});
|
|
2366
2366
|
|
|
2367
|
-
// src/engine/intent.
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
IntentRouter: () => IntentRouter
|
|
2371
|
-
});
|
|
2372
|
-
import { decodeChainEnvelope, decodeChainRequest } from "@nextera.one/axis-protocol";
|
|
2373
|
-
function observerRefKey(ref) {
|
|
2374
|
-
return typeof ref === "string" ? ref : ref.name;
|
|
2367
|
+
// src/engine/intent-builtins.ts
|
|
2368
|
+
function isBuiltinIntent(intent) {
|
|
2369
|
+
return BUILTIN_INTENTS.has(intent);
|
|
2375
2370
|
}
|
|
2376
|
-
function
|
|
2377
|
-
return
|
|
2371
|
+
function isChainExecIntent(intent) {
|
|
2372
|
+
return intent === "CHAIN.EXEC" || intent === "axis.chain.exec";
|
|
2378
2373
|
}
|
|
2379
|
-
function
|
|
2380
|
-
return
|
|
2374
|
+
function isIntentExecIntent(intent) {
|
|
2375
|
+
return intent === "INTENT.EXEC" || intent === "axis.intent.exec";
|
|
2376
|
+
}
|
|
2377
|
+
function routeSystemBuiltinIntent(intent, body, encoder) {
|
|
2378
|
+
if (intent === "system.ping" || intent === "public.ping") {
|
|
2379
|
+
return {
|
|
2380
|
+
ok: true,
|
|
2381
|
+
effect: "pong",
|
|
2382
|
+
headers: /* @__PURE__ */ new Map([[100, encoder.encode("AXIS_BACKEND_V1")]]),
|
|
2383
|
+
body: encoder.encode(
|
|
2384
|
+
JSON.stringify({
|
|
2385
|
+
status: "ok",
|
|
2386
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2387
|
+
version: "1.0.0"
|
|
2388
|
+
})
|
|
2389
|
+
)
|
|
2390
|
+
};
|
|
2391
|
+
}
|
|
2392
|
+
if (intent === "system.time") {
|
|
2393
|
+
const ts = Date.now().toString();
|
|
2394
|
+
return {
|
|
2395
|
+
ok: true,
|
|
2396
|
+
effect: "time",
|
|
2397
|
+
body: encoder.encode(
|
|
2398
|
+
JSON.stringify({
|
|
2399
|
+
ts,
|
|
2400
|
+
iso: (/* @__PURE__ */ new Date()).toISOString()
|
|
2401
|
+
})
|
|
2402
|
+
)
|
|
2403
|
+
};
|
|
2404
|
+
}
|
|
2405
|
+
if (intent === "system.echo") {
|
|
2406
|
+
return {
|
|
2407
|
+
ok: true,
|
|
2408
|
+
effect: "echo",
|
|
2409
|
+
body
|
|
2410
|
+
};
|
|
2411
|
+
}
|
|
2412
|
+
return void 0;
|
|
2381
2413
|
}
|
|
2414
|
+
var BUILTIN_INTENTS;
|
|
2415
|
+
var init_intent_builtins = __esm({
|
|
2416
|
+
"src/engine/intent-builtins.ts"() {
|
|
2417
|
+
BUILTIN_INTENTS = /* @__PURE__ */ new Set([
|
|
2418
|
+
"system.ping",
|
|
2419
|
+
"public.ping",
|
|
2420
|
+
"system.time",
|
|
2421
|
+
"system.echo",
|
|
2422
|
+
"CHAIN.EXEC",
|
|
2423
|
+
"axis.chain.exec",
|
|
2424
|
+
"INTENT.EXEC",
|
|
2425
|
+
"axis.intent.exec"
|
|
2426
|
+
]);
|
|
2427
|
+
}
|
|
2428
|
+
});
|
|
2429
|
+
|
|
2430
|
+
// src/engine/intent-proof-policy.ts
|
|
2431
|
+
import "reflect-metadata";
|
|
2382
2432
|
function mergeProofKinds(...proofGroups) {
|
|
2383
2433
|
const merged = /* @__PURE__ */ new Set();
|
|
2384
2434
|
for (const proofs of proofGroups) {
|
|
@@ -2395,6 +2445,80 @@ function accessProofKinds(isPublic, isAnonymous, isAuthorized) {
|
|
|
2395
2445
|
if (isAuthorized) proofs.push("AUTHORIZED");
|
|
2396
2446
|
return proofs;
|
|
2397
2447
|
}
|
|
2448
|
+
function resolveIntentProofPolicy(proto, methodName) {
|
|
2449
|
+
const methodProof = Reflect.getMetadata(
|
|
2450
|
+
REQUIRED_PROOF_METADATA_KEY,
|
|
2451
|
+
proto,
|
|
2452
|
+
methodName
|
|
2453
|
+
);
|
|
2454
|
+
const classProof = Reflect.getMetadata(
|
|
2455
|
+
REQUIRED_PROOF_METADATA_KEY,
|
|
2456
|
+
proto.constructor
|
|
2457
|
+
);
|
|
2458
|
+
const isPublicMethod = Reflect.getMetadata(
|
|
2459
|
+
AXIS_PUBLIC_KEY,
|
|
2460
|
+
proto,
|
|
2461
|
+
methodName
|
|
2462
|
+
);
|
|
2463
|
+
const isPublicClass = Reflect.getMetadata(
|
|
2464
|
+
AXIS_PUBLIC_KEY,
|
|
2465
|
+
proto.constructor
|
|
2466
|
+
);
|
|
2467
|
+
const isAnonymousMethod = Reflect.getMetadata(
|
|
2468
|
+
AXIS_ANONYMOUS_KEY,
|
|
2469
|
+
proto,
|
|
2470
|
+
methodName
|
|
2471
|
+
);
|
|
2472
|
+
const isAnonymousClass = Reflect.getMetadata(
|
|
2473
|
+
AXIS_ANONYMOUS_KEY,
|
|
2474
|
+
proto.constructor
|
|
2475
|
+
);
|
|
2476
|
+
const isAuthorizedMethod = Reflect.getMetadata(
|
|
2477
|
+
AXIS_AUTHORIZED_KEY,
|
|
2478
|
+
proto,
|
|
2479
|
+
methodName
|
|
2480
|
+
);
|
|
2481
|
+
const isAuthorizedClass = Reflect.getMetadata(
|
|
2482
|
+
AXIS_AUTHORIZED_KEY,
|
|
2483
|
+
proto.constructor
|
|
2484
|
+
);
|
|
2485
|
+
const methodPolicyProof = mergeProofKinds(
|
|
2486
|
+
methodProof,
|
|
2487
|
+
accessProofKinds(isPublicMethod, isAnonymousMethod, isAuthorizedMethod)
|
|
2488
|
+
);
|
|
2489
|
+
const classPolicyProof = mergeProofKinds(
|
|
2490
|
+
classProof,
|
|
2491
|
+
accessProofKinds(isPublicClass, isAnonymousClass, isAuthorizedClass)
|
|
2492
|
+
);
|
|
2493
|
+
const requiredProof = methodPolicyProof.length ? methodPolicyProof : classPolicyProof;
|
|
2494
|
+
return {
|
|
2495
|
+
requiredProof,
|
|
2496
|
+
isPublic: requiredProof.includes("NONE"),
|
|
2497
|
+
isAnonymous: requiredProof.includes("ANONYMOUS"),
|
|
2498
|
+
isAuthorized: requiredProof.includes("AUTHORIZED")
|
|
2499
|
+
};
|
|
2500
|
+
}
|
|
2501
|
+
var init_intent_proof_policy = __esm({
|
|
2502
|
+
"src/engine/intent-proof-policy.ts"() {
|
|
2503
|
+
init_intent_policy_decorator();
|
|
2504
|
+
}
|
|
2505
|
+
});
|
|
2506
|
+
|
|
2507
|
+
// src/engine/intent.router.ts
|
|
2508
|
+
var intent_router_exports = {};
|
|
2509
|
+
__export(intent_router_exports, {
|
|
2510
|
+
IntentRouter: () => IntentRouter
|
|
2511
|
+
});
|
|
2512
|
+
import { decodeChainEnvelope, decodeChainRequest } from "@nextera.one/axis-protocol";
|
|
2513
|
+
function observerRefKey(ref) {
|
|
2514
|
+
return typeof ref === "string" ? ref : ref.name;
|
|
2515
|
+
}
|
|
2516
|
+
function sensorRefKey(ref) {
|
|
2517
|
+
return typeof ref === "string" ? ref : ref.name;
|
|
2518
|
+
}
|
|
2519
|
+
function sensorBindingKey(binding) {
|
|
2520
|
+
return `${binding.when}:${sensorRefKey(binding.ref)}`;
|
|
2521
|
+
}
|
|
2398
2522
|
function mergeIntentSensorBindings(...sensorGroups) {
|
|
2399
2523
|
const merged = /* @__PURE__ */ new Map();
|
|
2400
2524
|
for (const group of sensorGroups) {
|
|
@@ -2450,7 +2574,7 @@ function normalizeChainConfig(decoratorConfig, intentConfig) {
|
|
|
2450
2574
|
...intentConfig
|
|
2451
2575
|
};
|
|
2452
2576
|
}
|
|
2453
|
-
var import_dto_schema,
|
|
2577
|
+
var import_dto_schema, IntentRouter;
|
|
2454
2578
|
var init_intent_router = __esm({
|
|
2455
2579
|
"src/engine/intent.router.ts"() {
|
|
2456
2580
|
init_handler_sensors_decorator();
|
|
@@ -2470,7 +2594,9 @@ var init_intent_router = __esm({
|
|
|
2470
2594
|
init_cce_pipeline();
|
|
2471
2595
|
init_axis_error();
|
|
2472
2596
|
init_constants();
|
|
2473
|
-
|
|
2597
|
+
init_intent_builtins();
|
|
2598
|
+
init_intent_proof_policy();
|
|
2599
|
+
IntentRouter = class _IntentRouter {
|
|
2474
2600
|
constructor(dependencyResolver, observerDispatcher, sensorRegistry) {
|
|
2475
2601
|
this.logger = createAxisLogger(_IntentRouter.name);
|
|
2476
2602
|
this.decoder = new TextDecoder();
|
|
@@ -2501,12 +2627,6 @@ var init_intent_router = __esm({
|
|
|
2501
2627
|
this.intentContracts = /* @__PURE__ */ new Map();
|
|
2502
2628
|
/** Per-intent required proof kinds */
|
|
2503
2629
|
this.intentRequiredProof = /* @__PURE__ */ new Map();
|
|
2504
|
-
/** Intents flagged as public (no auth required) */
|
|
2505
|
-
this.publicIntents = /* @__PURE__ */ new Set();
|
|
2506
|
-
/** Intents flagged as anonymous-session accessible */
|
|
2507
|
-
this.anonymousIntents = /* @__PURE__ */ new Set();
|
|
2508
|
-
/** Intents flagged as authorized-session accessible */
|
|
2509
|
-
this.authorizedIntents = /* @__PURE__ */ new Set();
|
|
2510
2630
|
/** Per-intent rate limit config */
|
|
2511
2631
|
this.intentRateLimits = /* @__PURE__ */ new Map();
|
|
2512
2632
|
/** CCE handler registry */
|
|
@@ -2537,10 +2657,10 @@ var init_intent_router = __esm({
|
|
|
2537
2657
|
}
|
|
2538
2658
|
has(intent) {
|
|
2539
2659
|
const resolved = this.resolveIntentAlias(intent);
|
|
2540
|
-
return this.handlers.has(resolved) ||
|
|
2660
|
+
return this.handlers.has(resolved) || isBuiltinIntent(resolved);
|
|
2541
2661
|
}
|
|
2542
2662
|
getRegisteredIntents() {
|
|
2543
|
-
return [...
|
|
2663
|
+
return [...BUILTIN_INTENTS, ...this.handlers.keys()];
|
|
2544
2664
|
}
|
|
2545
2665
|
getIntentEntry(intent) {
|
|
2546
2666
|
const resolved = this.resolveIntentAlias(intent);
|
|
@@ -2549,7 +2669,7 @@ var init_intent_router = __esm({
|
|
|
2549
2669
|
schema: this.intentSchemas.get(resolved),
|
|
2550
2670
|
validators: this.intentValidators.get(resolved),
|
|
2551
2671
|
hasSensors: this.intentSensors.has(resolved),
|
|
2552
|
-
builtin:
|
|
2672
|
+
builtin: isBuiltinIntent(resolved),
|
|
2553
2673
|
kind: this.intentKinds.get(resolved),
|
|
2554
2674
|
chain: this.intentChains.get(resolved),
|
|
2555
2675
|
capsulePolicy: this.intentCapsulePolicies.get(resolved),
|
|
@@ -2571,6 +2691,9 @@ var init_intent_router = __esm({
|
|
|
2571
2691
|
* @param {any} handler - The handler function or object
|
|
2572
2692
|
*/
|
|
2573
2693
|
register(intent, handler) {
|
|
2694
|
+
if (this.handlers.has(intent)) {
|
|
2695
|
+
this.logger.warn(`Intent ${intent} is already registered; replacing handler`);
|
|
2696
|
+
}
|
|
2574
2697
|
this.handlers.set(intent, handler);
|
|
2575
2698
|
if (typeof handler === "function" && handler.name) {
|
|
2576
2699
|
this.intentHandlerRefs.set(intent, handler.name);
|
|
@@ -2655,9 +2778,14 @@ var init_intent_router = __esm({
|
|
|
2655
2778
|
* Routes a decoded AXIS frame to the appropriate handler.
|
|
2656
2779
|
*
|
|
2657
2780
|
* **Precedence:**
|
|
2658
|
-
* 1.
|
|
2659
|
-
* 2.
|
|
2660
|
-
* 3.
|
|
2781
|
+
* 1. SDK meta-intents (`CHAIN.EXEC`, `INTENT.EXEC`)
|
|
2782
|
+
* 2. Dynamically registered handlers from modules
|
|
2783
|
+
* 3. Simple SDK built-in fallback (`system.ping`, `public.ping`, `system.time`, `system.echo`)
|
|
2784
|
+
*
|
|
2785
|
+
* Registered app handlers intentionally win over simple built-ins. This lets
|
|
2786
|
+
* applications attach sensors, rate limits, and custom responses to intents
|
|
2787
|
+
* like `system.ping` while keeping a default fallback for apps that do not
|
|
2788
|
+
* register their own handler.
|
|
2661
2789
|
*
|
|
2662
2790
|
* @param {AxisFrame} frame - The validated and decoded binary frame
|
|
2663
2791
|
* @returns {Promise<AxisEffect>} The resulting effect of the execution
|
|
@@ -2681,128 +2809,7 @@ var init_intent_router = __esm({
|
|
|
2681
2809
|
frame
|
|
2682
2810
|
});
|
|
2683
2811
|
let effect;
|
|
2684
|
-
|
|
2685
|
-
this.logger.debug("PING received");
|
|
2686
|
-
effect = {
|
|
2687
|
-
ok: true,
|
|
2688
|
-
effect: "pong",
|
|
2689
|
-
headers: /* @__PURE__ */ new Map([
|
|
2690
|
-
[100, new TextEncoder().encode("AXIS_BACKEND_V1")]
|
|
2691
|
-
]),
|
|
2692
|
-
body: new TextEncoder().encode(
|
|
2693
|
-
JSON.stringify({
|
|
2694
|
-
status: "ok",
|
|
2695
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2696
|
-
version: "1.0.0"
|
|
2697
|
-
})
|
|
2698
|
-
)
|
|
2699
|
-
};
|
|
2700
|
-
} else if (intent === "system.time") {
|
|
2701
|
-
const ts = Date.now().toString();
|
|
2702
|
-
effect = {
|
|
2703
|
-
ok: true,
|
|
2704
|
-
effect: "time",
|
|
2705
|
-
body: new TextEncoder().encode(
|
|
2706
|
-
JSON.stringify({
|
|
2707
|
-
ts,
|
|
2708
|
-
iso: (/* @__PURE__ */ new Date()).toISOString()
|
|
2709
|
-
})
|
|
2710
|
-
)
|
|
2711
|
-
};
|
|
2712
|
-
} else if (intent === "system.echo") {
|
|
2713
|
-
effect = {
|
|
2714
|
-
ok: true,
|
|
2715
|
-
effect: "echo",
|
|
2716
|
-
body: frame.body
|
|
2717
|
-
};
|
|
2718
|
-
} else if (intent === "CHAIN.EXEC" || intent === "axis.chain.exec") {
|
|
2719
|
-
const chainRequest = this.parseChainRequestBody(frame.body);
|
|
2720
|
-
effect = await this.executeChainRequest(frame, chainRequest);
|
|
2721
|
-
} else if (intent === "INTENT.EXEC" || intent === "axis.intent.exec") {
|
|
2722
|
-
const execBody = this.parseIntentExecBody(frame.body);
|
|
2723
|
-
const innerIntent = execBody.intent;
|
|
2724
|
-
const innerArgs = execBody.args || {};
|
|
2725
|
-
if (!innerIntent) {
|
|
2726
|
-
throw new Error("INTENT.EXEC missing inner intent");
|
|
2727
|
-
}
|
|
2728
|
-
this.logger.debug(`EXEC: routing to inner intent '${innerIntent}'`);
|
|
2729
|
-
const innerHeaders = new Map(frame.headers);
|
|
2730
|
-
innerHeaders.set(TLV_INTENT, this.encoder.encode(innerIntent));
|
|
2731
|
-
const inlineCapsule = this.toInlineCapsuleRecord(execBody.capsule);
|
|
2732
|
-
const capsuleId = this.extractInlineCapsuleId(inlineCapsule);
|
|
2733
|
-
if (capsuleId) {
|
|
2734
|
-
innerHeaders.set(TLV_CAPSULE, this.encoder.encode(capsuleId));
|
|
2735
|
-
innerHeaders.set(TLV_PROOF_REF, this.encoder.encode(capsuleId));
|
|
2736
|
-
}
|
|
2737
|
-
const innerFrame = withAxisExecutionContext(
|
|
2738
|
-
{
|
|
2739
|
-
...frame,
|
|
2740
|
-
headers: innerHeaders,
|
|
2741
|
-
body: this.encodeJson(innerArgs)
|
|
2742
|
-
},
|
|
2743
|
-
mergeAxisExecutionContext(getAxisExecutionContext(frame), {
|
|
2744
|
-
metaIntent: "INTENT.EXEC",
|
|
2745
|
-
actorId: this.getActorIdFromFrame(frame),
|
|
2746
|
-
inlineCapsule
|
|
2747
|
-
}) || {}
|
|
2748
|
-
);
|
|
2749
|
-
effect = await this.route(innerFrame);
|
|
2750
|
-
} else {
|
|
2751
|
-
const handler = this.handlers.get(intent);
|
|
2752
|
-
if (!handler) {
|
|
2753
|
-
throw new Error(`Intent not found: ${intent}`);
|
|
2754
|
-
}
|
|
2755
|
-
const sensorBindings = this.intentSensors.get(intent);
|
|
2756
|
-
if (sensorBindings && sensorBindings.length > 0) {
|
|
2757
|
-
await this.runIntentSensors(sensorBindings, intent, frame, "before");
|
|
2758
|
-
}
|
|
2759
|
-
const decoder = this.intentDecoders.get(intent);
|
|
2760
|
-
let decodedBody = frame.body;
|
|
2761
|
-
if (decoder) {
|
|
2762
|
-
try {
|
|
2763
|
-
decodedBody = decoder(Buffer.from(frame.body));
|
|
2764
|
-
} catch (decodeErr) {
|
|
2765
|
-
throw new Error(
|
|
2766
|
-
`IntentBody decode failed for ${intent}: ${decodeErr.message}`
|
|
2767
|
-
);
|
|
2768
|
-
}
|
|
2769
|
-
}
|
|
2770
|
-
this.enforceCapsulePolicy(
|
|
2771
|
-
intent,
|
|
2772
|
-
frame,
|
|
2773
|
-
decodedBody,
|
|
2774
|
-
this.getEffectiveCapsulePolicy(intent, frame)
|
|
2775
|
-
);
|
|
2776
|
-
if (typeof handler === "function") {
|
|
2777
|
-
const resultBody = decoder ? await handler(decodedBody, frame.headers) : await handler(frame.body, frame.headers);
|
|
2778
|
-
effect = {
|
|
2779
|
-
ok: true,
|
|
2780
|
-
effect: "complete",
|
|
2781
|
-
body: resultBody
|
|
2782
|
-
};
|
|
2783
|
-
} else {
|
|
2784
|
-
if (typeof handler.handle === "function") {
|
|
2785
|
-
effect = await handler.handle(frame);
|
|
2786
|
-
} else if (typeof handler.execute === "function") {
|
|
2787
|
-
const bodyRes = decoder ? await handler.execute(decodedBody, frame.headers) : await handler.execute(frame.body, frame.headers);
|
|
2788
|
-
effect = {
|
|
2789
|
-
ok: true,
|
|
2790
|
-
effect: "complete",
|
|
2791
|
-
body: bodyRes
|
|
2792
|
-
};
|
|
2793
|
-
} else {
|
|
2794
|
-
throw new Error(
|
|
2795
|
-
`Handler for ${intent} does not implement handle or execute`
|
|
2796
|
-
);
|
|
2797
|
-
}
|
|
2798
|
-
}
|
|
2799
|
-
if (sensorBindings && sensorBindings.length > 0) {
|
|
2800
|
-
await this.runIntentSensors(sensorBindings, intent, frame, "after", {
|
|
2801
|
-
decodedBody,
|
|
2802
|
-
effect
|
|
2803
|
-
});
|
|
2804
|
-
}
|
|
2805
|
-
}
|
|
2812
|
+
effect = await this.routeResolvedIntent(intent, frame);
|
|
2806
2813
|
await this.emitIntentObservers(observerBindings, {
|
|
2807
2814
|
event: "intent.completed",
|
|
2808
2815
|
timestamp: Date.now(),
|
|
@@ -2827,6 +2834,137 @@ var init_intent_router = __esm({
|
|
|
2827
2834
|
throw e;
|
|
2828
2835
|
}
|
|
2829
2836
|
}
|
|
2837
|
+
/**
|
|
2838
|
+
* Dispatches a resolved canonical intent to the correct execution path.
|
|
2839
|
+
* This keeps route() focused on observer/error lifecycle concerns.
|
|
2840
|
+
*/
|
|
2841
|
+
async routeResolvedIntent(intent, frame) {
|
|
2842
|
+
if (isChainExecIntent(intent)) {
|
|
2843
|
+
const chainRequest = this.parseChainRequestBody(frame.body);
|
|
2844
|
+
return this.executeChainRequest(frame, chainRequest);
|
|
2845
|
+
}
|
|
2846
|
+
if (isIntentExecIntent(intent)) {
|
|
2847
|
+
return this.routeIntentExec(frame);
|
|
2848
|
+
}
|
|
2849
|
+
if (this.handlers.has(intent)) {
|
|
2850
|
+
return this.routeRegisteredIntent(intent, frame);
|
|
2851
|
+
}
|
|
2852
|
+
const builtinEffect = routeSystemBuiltinIntent(
|
|
2853
|
+
intent,
|
|
2854
|
+
frame.body,
|
|
2855
|
+
this.encoder
|
|
2856
|
+
);
|
|
2857
|
+
if (builtinEffect) {
|
|
2858
|
+
if (intent === "system.ping" || intent === "public.ping") {
|
|
2859
|
+
this.logger.debug("PING received");
|
|
2860
|
+
}
|
|
2861
|
+
return builtinEffect;
|
|
2862
|
+
}
|
|
2863
|
+
return this.routeRegisteredIntent(intent, frame);
|
|
2864
|
+
}
|
|
2865
|
+
/**
|
|
2866
|
+
* Handles INTENT.EXEC by building an inner frame and routing it normally.
|
|
2867
|
+
* The recursive route call is intentional so sensors/observers/policies for
|
|
2868
|
+
* the inner intent stay identical to a direct request.
|
|
2869
|
+
*/
|
|
2870
|
+
async routeIntentExec(frame) {
|
|
2871
|
+
const execBody = this.parseIntentExecBody(frame.body);
|
|
2872
|
+
const innerIntent = execBody.intent;
|
|
2873
|
+
const innerArgs = execBody.args || {};
|
|
2874
|
+
if (!innerIntent) {
|
|
2875
|
+
throw new Error("INTENT.EXEC missing inner intent");
|
|
2876
|
+
}
|
|
2877
|
+
this.logger.debug(`EXEC: routing to inner intent '${innerIntent}'`);
|
|
2878
|
+
const innerHeaders = new Map(frame.headers);
|
|
2879
|
+
innerHeaders.set(TLV_INTENT, this.encoder.encode(innerIntent));
|
|
2880
|
+
const inlineCapsule = this.toInlineCapsuleRecord(execBody.capsule);
|
|
2881
|
+
const capsuleId = this.extractInlineCapsuleId(inlineCapsule);
|
|
2882
|
+
if (capsuleId) {
|
|
2883
|
+
innerHeaders.set(TLV_CAPSULE, this.encoder.encode(capsuleId));
|
|
2884
|
+
innerHeaders.set(TLV_PROOF_REF, this.encoder.encode(capsuleId));
|
|
2885
|
+
}
|
|
2886
|
+
const innerFrame = withAxisExecutionContext(
|
|
2887
|
+
{
|
|
2888
|
+
...frame,
|
|
2889
|
+
headers: innerHeaders,
|
|
2890
|
+
body: this.encodeJson(innerArgs)
|
|
2891
|
+
},
|
|
2892
|
+
mergeAxisExecutionContext(getAxisExecutionContext(frame), {
|
|
2893
|
+
metaIntent: "INTENT.EXEC",
|
|
2894
|
+
actorId: this.getActorIdFromFrame(frame),
|
|
2895
|
+
inlineCapsule
|
|
2896
|
+
}) || {}
|
|
2897
|
+
);
|
|
2898
|
+
return this.route(innerFrame);
|
|
2899
|
+
}
|
|
2900
|
+
/**
|
|
2901
|
+
* Executes an app-registered intent: before sensors, body decode, capsule
|
|
2902
|
+
* policy, handler invocation, then after sensors.
|
|
2903
|
+
*/
|
|
2904
|
+
async routeRegisteredIntent(intent, frame) {
|
|
2905
|
+
const handler = this.handlers.get(intent);
|
|
2906
|
+
if (!handler) {
|
|
2907
|
+
throw new Error(`Intent not found: ${intent}`);
|
|
2908
|
+
}
|
|
2909
|
+
const sensorBindings = this.intentSensors.get(intent);
|
|
2910
|
+
if (sensorBindings && sensorBindings.length > 0) {
|
|
2911
|
+
await this.runIntentSensors(sensorBindings, intent, frame, "before");
|
|
2912
|
+
}
|
|
2913
|
+
const decoder = this.intentDecoders.get(intent);
|
|
2914
|
+
const decodedBody = this.decodeIntentBody(intent, frame, decoder);
|
|
2915
|
+
this.enforceCapsulePolicy(
|
|
2916
|
+
intent,
|
|
2917
|
+
frame,
|
|
2918
|
+
decodedBody,
|
|
2919
|
+
this.getEffectiveCapsulePolicy(intent, frame)
|
|
2920
|
+
);
|
|
2921
|
+
const effect = await this.invokeRegisteredHandler(
|
|
2922
|
+
intent,
|
|
2923
|
+
handler,
|
|
2924
|
+
frame,
|
|
2925
|
+
decoder,
|
|
2926
|
+
decodedBody
|
|
2927
|
+
);
|
|
2928
|
+
if (sensorBindings && sensorBindings.length > 0) {
|
|
2929
|
+
await this.runIntentSensors(sensorBindings, intent, frame, "after", {
|
|
2930
|
+
decodedBody,
|
|
2931
|
+
effect
|
|
2932
|
+
});
|
|
2933
|
+
}
|
|
2934
|
+
return effect;
|
|
2935
|
+
}
|
|
2936
|
+
decodeIntentBody(intent, frame, decoder) {
|
|
2937
|
+
if (!decoder) return frame.body;
|
|
2938
|
+
try {
|
|
2939
|
+
return decoder(Buffer.from(frame.body));
|
|
2940
|
+
} catch (decodeErr) {
|
|
2941
|
+
throw new Error(
|
|
2942
|
+
`IntentBody decode failed for ${intent}: ${decodeErr.message}`
|
|
2943
|
+
);
|
|
2944
|
+
}
|
|
2945
|
+
}
|
|
2946
|
+
async invokeRegisteredHandler(intent, handler, frame, decoder, decodedBody) {
|
|
2947
|
+
if (typeof handler === "function") {
|
|
2948
|
+
const resultBody = decoder ? await handler(decodedBody, frame.headers) : await handler(frame.body, frame.headers);
|
|
2949
|
+
return {
|
|
2950
|
+
ok: true,
|
|
2951
|
+
effect: "complete",
|
|
2952
|
+
body: resultBody
|
|
2953
|
+
};
|
|
2954
|
+
}
|
|
2955
|
+
if (typeof handler.handle === "function") {
|
|
2956
|
+
return handler.handle(frame);
|
|
2957
|
+
}
|
|
2958
|
+
if (typeof handler.execute === "function") {
|
|
2959
|
+
const bodyRes = decoder ? await handler.execute(decodedBody, frame.headers) : await handler.execute(frame.body, frame.headers);
|
|
2960
|
+
return {
|
|
2961
|
+
ok: true,
|
|
2962
|
+
effect: "complete",
|
|
2963
|
+
body: bodyRes
|
|
2964
|
+
};
|
|
2965
|
+
}
|
|
2966
|
+
throw new Error(`Handler for ${intent} does not implement handle or execute`);
|
|
2967
|
+
}
|
|
2830
2968
|
logIntent(intent, start, ok, error) {
|
|
2831
2969
|
const diff = process.hrtime(start);
|
|
2832
2970
|
const ms = (diff[0] * 1e3 + diff[1] / 1e6).toFixed(2);
|
|
@@ -2920,62 +3058,9 @@ var init_intent_router = __esm({
|
|
|
2920
3058
|
if (contract) {
|
|
2921
3059
|
this.intentContracts.set(intent, contract);
|
|
2922
3060
|
}
|
|
2923
|
-
const
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
methodName
|
|
2927
|
-
);
|
|
2928
|
-
const classProof = Reflect.getMetadata(
|
|
2929
|
-
REQUIRED_PROOF_METADATA_KEY,
|
|
2930
|
-
proto.constructor
|
|
2931
|
-
);
|
|
2932
|
-
const isPublicMethod = Reflect.getMetadata(
|
|
2933
|
-
AXIS_PUBLIC_KEY,
|
|
2934
|
-
proto,
|
|
2935
|
-
methodName
|
|
2936
|
-
);
|
|
2937
|
-
const isPublicClass = Reflect.getMetadata(
|
|
2938
|
-
AXIS_PUBLIC_KEY,
|
|
2939
|
-
proto.constructor
|
|
2940
|
-
);
|
|
2941
|
-
const isAnonMethod = Reflect.getMetadata(
|
|
2942
|
-
AXIS_ANONYMOUS_KEY,
|
|
2943
|
-
proto,
|
|
2944
|
-
methodName
|
|
2945
|
-
);
|
|
2946
|
-
const isAnonClass = Reflect.getMetadata(
|
|
2947
|
-
AXIS_ANONYMOUS_KEY,
|
|
2948
|
-
proto.constructor
|
|
2949
|
-
);
|
|
2950
|
-
const isAuthorizedMethod = Reflect.getMetadata(
|
|
2951
|
-
AXIS_AUTHORIZED_KEY,
|
|
2952
|
-
proto,
|
|
2953
|
-
methodName
|
|
2954
|
-
);
|
|
2955
|
-
const isAuthorizedClass = Reflect.getMetadata(
|
|
2956
|
-
AXIS_AUTHORIZED_KEY,
|
|
2957
|
-
proto.constructor
|
|
2958
|
-
);
|
|
2959
|
-
const methodPolicyProof = mergeProofKinds(
|
|
2960
|
-
methodProof,
|
|
2961
|
-
accessProofKinds(isPublicMethod, isAnonMethod, isAuthorizedMethod)
|
|
2962
|
-
);
|
|
2963
|
-
const classPolicyProof = mergeProofKinds(
|
|
2964
|
-
classProof,
|
|
2965
|
-
accessProofKinds(isPublicClass, isAnonClass, isAuthorizedClass)
|
|
2966
|
-
);
|
|
2967
|
-
const requiredProof = methodPolicyProof.length ? methodPolicyProof : classPolicyProof;
|
|
2968
|
-
if (requiredProof.length > 0) {
|
|
2969
|
-
this.intentRequiredProof.set(intent, requiredProof);
|
|
2970
|
-
}
|
|
2971
|
-
if (requiredProof.includes("NONE")) {
|
|
2972
|
-
this.publicIntents.add(intent);
|
|
2973
|
-
}
|
|
2974
|
-
if (requiredProof.includes("ANONYMOUS")) {
|
|
2975
|
-
this.anonymousIntents.add(intent);
|
|
2976
|
-
}
|
|
2977
|
-
if (requiredProof.includes("AUTHORIZED")) {
|
|
2978
|
-
this.authorizedIntents.add(intent);
|
|
3061
|
+
const proofPolicy = resolveIntentProofPolicy(proto, methodName);
|
|
3062
|
+
if (proofPolicy.requiredProof.length > 0) {
|
|
3063
|
+
this.intentRequiredProof.set(intent, proofPolicy.requiredProof);
|
|
2979
3064
|
}
|
|
2980
3065
|
const rateLimit = Reflect.getMetadata(
|
|
2981
3066
|
AXIS_RATE_LIMIT_KEY,
|
|
@@ -2997,13 +3082,13 @@ var init_intent_router = __esm({
|
|
|
2997
3082
|
return this.intentRequiredProof.get(this.resolveIntentAlias(intent));
|
|
2998
3083
|
}
|
|
2999
3084
|
isPublic(intent) {
|
|
3000
|
-
return this.
|
|
3085
|
+
return this.getRequiredProof(intent)?.includes("NONE") ?? false;
|
|
3001
3086
|
}
|
|
3002
3087
|
isAnonymous(intent) {
|
|
3003
|
-
return this.
|
|
3088
|
+
return this.getRequiredProof(intent)?.includes("ANONYMOUS") ?? false;
|
|
3004
3089
|
}
|
|
3005
3090
|
isAuthorized(intent) {
|
|
3006
|
-
return this.
|
|
3091
|
+
return this.getRequiredProof(intent)?.includes("AUTHORIZED") ?? false;
|
|
3007
3092
|
}
|
|
3008
3093
|
getRateLimit(intent) {
|
|
3009
3094
|
return this.intentRateLimits.get(this.resolveIntentAlias(intent));
|
|
@@ -3024,7 +3109,7 @@ var init_intent_router = __esm({
|
|
|
3024
3109
|
}
|
|
3025
3110
|
/** The system/builtin intents (ping, time, echo, chain, intent.exec). */
|
|
3026
3111
|
getSystemIntents() {
|
|
3027
|
-
return [...
|
|
3112
|
+
return [...BUILTIN_INTENTS];
|
|
3028
3113
|
}
|
|
3029
3114
|
/** True if every intent in the handler is public, or any one is public — returns true if ANY intent is @AxisPublic. */
|
|
3030
3115
|
isHandlerPublic(handlerName) {
|
|
@@ -3097,7 +3182,7 @@ var init_intent_router = __esm({
|
|
|
3097
3182
|
* canonical intent. Existing exact intent names always win.
|
|
3098
3183
|
*/
|
|
3099
3184
|
resolveIntentAlias(intent) {
|
|
3100
|
-
if (this.handlers.has(intent) ||
|
|
3185
|
+
if (this.handlers.has(intent) || isBuiltinIntent(intent)) {
|
|
3101
3186
|
return intent;
|
|
3102
3187
|
}
|
|
3103
3188
|
const separator = "...";
|
|
@@ -3621,18 +3706,6 @@ var init_intent_router = __esm({
|
|
|
3621
3706
|
this.intentSchemas.set(meta.intent, schema);
|
|
3622
3707
|
}
|
|
3623
3708
|
};
|
|
3624
|
-
/** Intents handled inline in route() — not in `handlers` map */
|
|
3625
|
-
_IntentRouter.BUILTIN_INTENTS = /* @__PURE__ */ new Set([
|
|
3626
|
-
"system.ping",
|
|
3627
|
-
"public.ping",
|
|
3628
|
-
"system.time",
|
|
3629
|
-
"system.echo",
|
|
3630
|
-
"CHAIN.EXEC",
|
|
3631
|
-
"axis.chain.exec",
|
|
3632
|
-
"INTENT.EXEC",
|
|
3633
|
-
"axis.intent.exec"
|
|
3634
|
-
]);
|
|
3635
|
-
IntentRouter = _IntentRouter;
|
|
3636
3709
|
}
|
|
3637
3710
|
});
|
|
3638
3711
|
|