@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/sensors/index.mjs
CHANGED
|
@@ -2508,21 +2508,71 @@ var init_axis_error = __esm({
|
|
|
2508
2508
|
}
|
|
2509
2509
|
});
|
|
2510
2510
|
|
|
2511
|
-
// src/engine/intent.
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
IntentRouter: () => IntentRouter
|
|
2515
|
-
});
|
|
2516
|
-
import { decodeChainEnvelope, decodeChainRequest } from "@nextera.one/axis-protocol";
|
|
2517
|
-
function observerRefKey(ref) {
|
|
2518
|
-
return typeof ref === "string" ? ref : ref.name;
|
|
2511
|
+
// src/engine/intent-builtins.ts
|
|
2512
|
+
function isBuiltinIntent(intent) {
|
|
2513
|
+
return BUILTIN_INTENTS.has(intent);
|
|
2519
2514
|
}
|
|
2520
|
-
function
|
|
2521
|
-
return
|
|
2515
|
+
function isChainExecIntent(intent) {
|
|
2516
|
+
return intent === "CHAIN.EXEC" || intent === "axis.chain.exec";
|
|
2522
2517
|
}
|
|
2523
|
-
function
|
|
2524
|
-
return
|
|
2518
|
+
function isIntentExecIntent(intent) {
|
|
2519
|
+
return intent === "INTENT.EXEC" || intent === "axis.intent.exec";
|
|
2520
|
+
}
|
|
2521
|
+
function routeSystemBuiltinIntent(intent, body, encoder) {
|
|
2522
|
+
if (intent === "system.ping" || intent === "public.ping") {
|
|
2523
|
+
return {
|
|
2524
|
+
ok: true,
|
|
2525
|
+
effect: "pong",
|
|
2526
|
+
headers: /* @__PURE__ */ new Map([[100, encoder.encode("AXIS_BACKEND_V1")]]),
|
|
2527
|
+
body: encoder.encode(
|
|
2528
|
+
JSON.stringify({
|
|
2529
|
+
status: "ok",
|
|
2530
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2531
|
+
version: "1.0.0"
|
|
2532
|
+
})
|
|
2533
|
+
)
|
|
2534
|
+
};
|
|
2535
|
+
}
|
|
2536
|
+
if (intent === "system.time") {
|
|
2537
|
+
const ts = Date.now().toString();
|
|
2538
|
+
return {
|
|
2539
|
+
ok: true,
|
|
2540
|
+
effect: "time",
|
|
2541
|
+
body: encoder.encode(
|
|
2542
|
+
JSON.stringify({
|
|
2543
|
+
ts,
|
|
2544
|
+
iso: (/* @__PURE__ */ new Date()).toISOString()
|
|
2545
|
+
})
|
|
2546
|
+
)
|
|
2547
|
+
};
|
|
2548
|
+
}
|
|
2549
|
+
if (intent === "system.echo") {
|
|
2550
|
+
return {
|
|
2551
|
+
ok: true,
|
|
2552
|
+
effect: "echo",
|
|
2553
|
+
body
|
|
2554
|
+
};
|
|
2555
|
+
}
|
|
2556
|
+
return void 0;
|
|
2525
2557
|
}
|
|
2558
|
+
var BUILTIN_INTENTS;
|
|
2559
|
+
var init_intent_builtins = __esm({
|
|
2560
|
+
"src/engine/intent-builtins.ts"() {
|
|
2561
|
+
BUILTIN_INTENTS = /* @__PURE__ */ new Set([
|
|
2562
|
+
"system.ping",
|
|
2563
|
+
"public.ping",
|
|
2564
|
+
"system.time",
|
|
2565
|
+
"system.echo",
|
|
2566
|
+
"CHAIN.EXEC",
|
|
2567
|
+
"axis.chain.exec",
|
|
2568
|
+
"INTENT.EXEC",
|
|
2569
|
+
"axis.intent.exec"
|
|
2570
|
+
]);
|
|
2571
|
+
}
|
|
2572
|
+
});
|
|
2573
|
+
|
|
2574
|
+
// src/engine/intent-proof-policy.ts
|
|
2575
|
+
import "reflect-metadata";
|
|
2526
2576
|
function mergeProofKinds(...proofGroups) {
|
|
2527
2577
|
const merged = /* @__PURE__ */ new Set();
|
|
2528
2578
|
for (const proofs of proofGroups) {
|
|
@@ -2539,6 +2589,80 @@ function accessProofKinds(isPublic, isAnonymous, isAuthorized) {
|
|
|
2539
2589
|
if (isAuthorized) proofs.push("AUTHORIZED");
|
|
2540
2590
|
return proofs;
|
|
2541
2591
|
}
|
|
2592
|
+
function resolveIntentProofPolicy(proto, methodName) {
|
|
2593
|
+
const methodProof = Reflect.getMetadata(
|
|
2594
|
+
REQUIRED_PROOF_METADATA_KEY,
|
|
2595
|
+
proto,
|
|
2596
|
+
methodName
|
|
2597
|
+
);
|
|
2598
|
+
const classProof = Reflect.getMetadata(
|
|
2599
|
+
REQUIRED_PROOF_METADATA_KEY,
|
|
2600
|
+
proto.constructor
|
|
2601
|
+
);
|
|
2602
|
+
const isPublicMethod = Reflect.getMetadata(
|
|
2603
|
+
AXIS_PUBLIC_KEY,
|
|
2604
|
+
proto,
|
|
2605
|
+
methodName
|
|
2606
|
+
);
|
|
2607
|
+
const isPublicClass = Reflect.getMetadata(
|
|
2608
|
+
AXIS_PUBLIC_KEY,
|
|
2609
|
+
proto.constructor
|
|
2610
|
+
);
|
|
2611
|
+
const isAnonymousMethod = Reflect.getMetadata(
|
|
2612
|
+
AXIS_ANONYMOUS_KEY,
|
|
2613
|
+
proto,
|
|
2614
|
+
methodName
|
|
2615
|
+
);
|
|
2616
|
+
const isAnonymousClass = Reflect.getMetadata(
|
|
2617
|
+
AXIS_ANONYMOUS_KEY,
|
|
2618
|
+
proto.constructor
|
|
2619
|
+
);
|
|
2620
|
+
const isAuthorizedMethod = Reflect.getMetadata(
|
|
2621
|
+
AXIS_AUTHORIZED_KEY,
|
|
2622
|
+
proto,
|
|
2623
|
+
methodName
|
|
2624
|
+
);
|
|
2625
|
+
const isAuthorizedClass = Reflect.getMetadata(
|
|
2626
|
+
AXIS_AUTHORIZED_KEY,
|
|
2627
|
+
proto.constructor
|
|
2628
|
+
);
|
|
2629
|
+
const methodPolicyProof = mergeProofKinds(
|
|
2630
|
+
methodProof,
|
|
2631
|
+
accessProofKinds(isPublicMethod, isAnonymousMethod, isAuthorizedMethod)
|
|
2632
|
+
);
|
|
2633
|
+
const classPolicyProof = mergeProofKinds(
|
|
2634
|
+
classProof,
|
|
2635
|
+
accessProofKinds(isPublicClass, isAnonymousClass, isAuthorizedClass)
|
|
2636
|
+
);
|
|
2637
|
+
const requiredProof = methodPolicyProof.length ? methodPolicyProof : classPolicyProof;
|
|
2638
|
+
return {
|
|
2639
|
+
requiredProof,
|
|
2640
|
+
isPublic: requiredProof.includes("NONE"),
|
|
2641
|
+
isAnonymous: requiredProof.includes("ANONYMOUS"),
|
|
2642
|
+
isAuthorized: requiredProof.includes("AUTHORIZED")
|
|
2643
|
+
};
|
|
2644
|
+
}
|
|
2645
|
+
var init_intent_proof_policy = __esm({
|
|
2646
|
+
"src/engine/intent-proof-policy.ts"() {
|
|
2647
|
+
init_intent_policy_decorator();
|
|
2648
|
+
}
|
|
2649
|
+
});
|
|
2650
|
+
|
|
2651
|
+
// src/engine/intent.router.ts
|
|
2652
|
+
var intent_router_exports = {};
|
|
2653
|
+
__export(intent_router_exports, {
|
|
2654
|
+
IntentRouter: () => IntentRouter
|
|
2655
|
+
});
|
|
2656
|
+
import { decodeChainEnvelope, decodeChainRequest } from "@nextera.one/axis-protocol";
|
|
2657
|
+
function observerRefKey(ref) {
|
|
2658
|
+
return typeof ref === "string" ? ref : ref.name;
|
|
2659
|
+
}
|
|
2660
|
+
function sensorRefKey(ref) {
|
|
2661
|
+
return typeof ref === "string" ? ref : ref.name;
|
|
2662
|
+
}
|
|
2663
|
+
function sensorBindingKey(binding) {
|
|
2664
|
+
return `${binding.when}:${sensorRefKey(binding.ref)}`;
|
|
2665
|
+
}
|
|
2542
2666
|
function mergeIntentSensorBindings(...sensorGroups) {
|
|
2543
2667
|
const merged = /* @__PURE__ */ new Map();
|
|
2544
2668
|
for (const group of sensorGroups) {
|
|
@@ -2594,7 +2718,7 @@ function normalizeChainConfig(decoratorConfig, intentConfig) {
|
|
|
2594
2718
|
...intentConfig
|
|
2595
2719
|
};
|
|
2596
2720
|
}
|
|
2597
|
-
var import_dto_schema,
|
|
2721
|
+
var import_dto_schema, IntentRouter;
|
|
2598
2722
|
var init_intent_router = __esm({
|
|
2599
2723
|
"src/engine/intent.router.ts"() {
|
|
2600
2724
|
init_handler_sensors_decorator();
|
|
@@ -2614,7 +2738,9 @@ var init_intent_router = __esm({
|
|
|
2614
2738
|
init_cce_pipeline();
|
|
2615
2739
|
init_axis_error();
|
|
2616
2740
|
init_constants();
|
|
2617
|
-
|
|
2741
|
+
init_intent_builtins();
|
|
2742
|
+
init_intent_proof_policy();
|
|
2743
|
+
IntentRouter = class _IntentRouter {
|
|
2618
2744
|
constructor(dependencyResolver, observerDispatcher, sensorRegistry) {
|
|
2619
2745
|
this.logger = createAxisLogger(_IntentRouter.name);
|
|
2620
2746
|
this.decoder = new TextDecoder();
|
|
@@ -2645,12 +2771,6 @@ var init_intent_router = __esm({
|
|
|
2645
2771
|
this.intentContracts = /* @__PURE__ */ new Map();
|
|
2646
2772
|
/** Per-intent required proof kinds */
|
|
2647
2773
|
this.intentRequiredProof = /* @__PURE__ */ new Map();
|
|
2648
|
-
/** Intents flagged as public (no auth required) */
|
|
2649
|
-
this.publicIntents = /* @__PURE__ */ new Set();
|
|
2650
|
-
/** Intents flagged as anonymous-session accessible */
|
|
2651
|
-
this.anonymousIntents = /* @__PURE__ */ new Set();
|
|
2652
|
-
/** Intents flagged as authorized-session accessible */
|
|
2653
|
-
this.authorizedIntents = /* @__PURE__ */ new Set();
|
|
2654
2774
|
/** Per-intent rate limit config */
|
|
2655
2775
|
this.intentRateLimits = /* @__PURE__ */ new Map();
|
|
2656
2776
|
/** CCE handler registry */
|
|
@@ -2681,10 +2801,10 @@ var init_intent_router = __esm({
|
|
|
2681
2801
|
}
|
|
2682
2802
|
has(intent) {
|
|
2683
2803
|
const resolved = this.resolveIntentAlias(intent);
|
|
2684
|
-
return this.handlers.has(resolved) ||
|
|
2804
|
+
return this.handlers.has(resolved) || isBuiltinIntent(resolved);
|
|
2685
2805
|
}
|
|
2686
2806
|
getRegisteredIntents() {
|
|
2687
|
-
return [...
|
|
2807
|
+
return [...BUILTIN_INTENTS, ...this.handlers.keys()];
|
|
2688
2808
|
}
|
|
2689
2809
|
getIntentEntry(intent) {
|
|
2690
2810
|
const resolved = this.resolveIntentAlias(intent);
|
|
@@ -2693,7 +2813,7 @@ var init_intent_router = __esm({
|
|
|
2693
2813
|
schema: this.intentSchemas.get(resolved),
|
|
2694
2814
|
validators: this.intentValidators.get(resolved),
|
|
2695
2815
|
hasSensors: this.intentSensors.has(resolved),
|
|
2696
|
-
builtin:
|
|
2816
|
+
builtin: isBuiltinIntent(resolved),
|
|
2697
2817
|
kind: this.intentKinds.get(resolved),
|
|
2698
2818
|
chain: this.intentChains.get(resolved),
|
|
2699
2819
|
capsulePolicy: this.intentCapsulePolicies.get(resolved),
|
|
@@ -2715,6 +2835,9 @@ var init_intent_router = __esm({
|
|
|
2715
2835
|
* @param {any} handler - The handler function or object
|
|
2716
2836
|
*/
|
|
2717
2837
|
register(intent, handler) {
|
|
2838
|
+
if (this.handlers.has(intent)) {
|
|
2839
|
+
this.logger.warn(`Intent ${intent} is already registered; replacing handler`);
|
|
2840
|
+
}
|
|
2718
2841
|
this.handlers.set(intent, handler);
|
|
2719
2842
|
if (typeof handler === "function" && handler.name) {
|
|
2720
2843
|
this.intentHandlerRefs.set(intent, handler.name);
|
|
@@ -2799,9 +2922,14 @@ var init_intent_router = __esm({
|
|
|
2799
2922
|
* Routes a decoded AXIS frame to the appropriate handler.
|
|
2800
2923
|
*
|
|
2801
2924
|
* **Precedence:**
|
|
2802
|
-
* 1.
|
|
2803
|
-
* 2.
|
|
2804
|
-
* 3.
|
|
2925
|
+
* 1. SDK meta-intents (`CHAIN.EXEC`, `INTENT.EXEC`)
|
|
2926
|
+
* 2. Dynamically registered handlers from modules
|
|
2927
|
+
* 3. Simple SDK built-in fallback (`system.ping`, `public.ping`, `system.time`, `system.echo`)
|
|
2928
|
+
*
|
|
2929
|
+
* Registered app handlers intentionally win over simple built-ins. This lets
|
|
2930
|
+
* applications attach sensors, rate limits, and custom responses to intents
|
|
2931
|
+
* like `system.ping` while keeping a default fallback for apps that do not
|
|
2932
|
+
* register their own handler.
|
|
2805
2933
|
*
|
|
2806
2934
|
* @param {AxisFrame} frame - The validated and decoded binary frame
|
|
2807
2935
|
* @returns {Promise<AxisEffect>} The resulting effect of the execution
|
|
@@ -2825,128 +2953,7 @@ var init_intent_router = __esm({
|
|
|
2825
2953
|
frame
|
|
2826
2954
|
});
|
|
2827
2955
|
let effect;
|
|
2828
|
-
|
|
2829
|
-
this.logger.debug("PING received");
|
|
2830
|
-
effect = {
|
|
2831
|
-
ok: true,
|
|
2832
|
-
effect: "pong",
|
|
2833
|
-
headers: /* @__PURE__ */ new Map([
|
|
2834
|
-
[100, new TextEncoder().encode("AXIS_BACKEND_V1")]
|
|
2835
|
-
]),
|
|
2836
|
-
body: new TextEncoder().encode(
|
|
2837
|
-
JSON.stringify({
|
|
2838
|
-
status: "ok",
|
|
2839
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2840
|
-
version: "1.0.0"
|
|
2841
|
-
})
|
|
2842
|
-
)
|
|
2843
|
-
};
|
|
2844
|
-
} else if (intent === "system.time") {
|
|
2845
|
-
const ts = Date.now().toString();
|
|
2846
|
-
effect = {
|
|
2847
|
-
ok: true,
|
|
2848
|
-
effect: "time",
|
|
2849
|
-
body: new TextEncoder().encode(
|
|
2850
|
-
JSON.stringify({
|
|
2851
|
-
ts,
|
|
2852
|
-
iso: (/* @__PURE__ */ new Date()).toISOString()
|
|
2853
|
-
})
|
|
2854
|
-
)
|
|
2855
|
-
};
|
|
2856
|
-
} else if (intent === "system.echo") {
|
|
2857
|
-
effect = {
|
|
2858
|
-
ok: true,
|
|
2859
|
-
effect: "echo",
|
|
2860
|
-
body: frame.body
|
|
2861
|
-
};
|
|
2862
|
-
} else if (intent === "CHAIN.EXEC" || intent === "axis.chain.exec") {
|
|
2863
|
-
const chainRequest = this.parseChainRequestBody(frame.body);
|
|
2864
|
-
effect = await this.executeChainRequest(frame, chainRequest);
|
|
2865
|
-
} else if (intent === "INTENT.EXEC" || intent === "axis.intent.exec") {
|
|
2866
|
-
const execBody = this.parseIntentExecBody(frame.body);
|
|
2867
|
-
const innerIntent = execBody.intent;
|
|
2868
|
-
const innerArgs = execBody.args || {};
|
|
2869
|
-
if (!innerIntent) {
|
|
2870
|
-
throw new Error("INTENT.EXEC missing inner intent");
|
|
2871
|
-
}
|
|
2872
|
-
this.logger.debug(`EXEC: routing to inner intent '${innerIntent}'`);
|
|
2873
|
-
const innerHeaders = new Map(frame.headers);
|
|
2874
|
-
innerHeaders.set(TLV_INTENT, this.encoder.encode(innerIntent));
|
|
2875
|
-
const inlineCapsule = this.toInlineCapsuleRecord(execBody.capsule);
|
|
2876
|
-
const capsuleId = this.extractInlineCapsuleId(inlineCapsule);
|
|
2877
|
-
if (capsuleId) {
|
|
2878
|
-
innerHeaders.set(TLV_CAPSULE, this.encoder.encode(capsuleId));
|
|
2879
|
-
innerHeaders.set(TLV_PROOF_REF, this.encoder.encode(capsuleId));
|
|
2880
|
-
}
|
|
2881
|
-
const innerFrame = withAxisExecutionContext(
|
|
2882
|
-
{
|
|
2883
|
-
...frame,
|
|
2884
|
-
headers: innerHeaders,
|
|
2885
|
-
body: this.encodeJson(innerArgs)
|
|
2886
|
-
},
|
|
2887
|
-
mergeAxisExecutionContext(getAxisExecutionContext(frame), {
|
|
2888
|
-
metaIntent: "INTENT.EXEC",
|
|
2889
|
-
actorId: this.getActorIdFromFrame(frame),
|
|
2890
|
-
inlineCapsule
|
|
2891
|
-
}) || {}
|
|
2892
|
-
);
|
|
2893
|
-
effect = await this.route(innerFrame);
|
|
2894
|
-
} else {
|
|
2895
|
-
const handler = this.handlers.get(intent);
|
|
2896
|
-
if (!handler) {
|
|
2897
|
-
throw new Error(`Intent not found: ${intent}`);
|
|
2898
|
-
}
|
|
2899
|
-
const sensorBindings = this.intentSensors.get(intent);
|
|
2900
|
-
if (sensorBindings && sensorBindings.length > 0) {
|
|
2901
|
-
await this.runIntentSensors(sensorBindings, intent, frame, "before");
|
|
2902
|
-
}
|
|
2903
|
-
const decoder = this.intentDecoders.get(intent);
|
|
2904
|
-
let decodedBody = frame.body;
|
|
2905
|
-
if (decoder) {
|
|
2906
|
-
try {
|
|
2907
|
-
decodedBody = decoder(Buffer.from(frame.body));
|
|
2908
|
-
} catch (decodeErr) {
|
|
2909
|
-
throw new Error(
|
|
2910
|
-
`IntentBody decode failed for ${intent}: ${decodeErr.message}`
|
|
2911
|
-
);
|
|
2912
|
-
}
|
|
2913
|
-
}
|
|
2914
|
-
this.enforceCapsulePolicy(
|
|
2915
|
-
intent,
|
|
2916
|
-
frame,
|
|
2917
|
-
decodedBody,
|
|
2918
|
-
this.getEffectiveCapsulePolicy(intent, frame)
|
|
2919
|
-
);
|
|
2920
|
-
if (typeof handler === "function") {
|
|
2921
|
-
const resultBody = decoder ? await handler(decodedBody, frame.headers) : await handler(frame.body, frame.headers);
|
|
2922
|
-
effect = {
|
|
2923
|
-
ok: true,
|
|
2924
|
-
effect: "complete",
|
|
2925
|
-
body: resultBody
|
|
2926
|
-
};
|
|
2927
|
-
} else {
|
|
2928
|
-
if (typeof handler.handle === "function") {
|
|
2929
|
-
effect = await handler.handle(frame);
|
|
2930
|
-
} else if (typeof handler.execute === "function") {
|
|
2931
|
-
const bodyRes = decoder ? await handler.execute(decodedBody, frame.headers) : await handler.execute(frame.body, frame.headers);
|
|
2932
|
-
effect = {
|
|
2933
|
-
ok: true,
|
|
2934
|
-
effect: "complete",
|
|
2935
|
-
body: bodyRes
|
|
2936
|
-
};
|
|
2937
|
-
} else {
|
|
2938
|
-
throw new Error(
|
|
2939
|
-
`Handler for ${intent} does not implement handle or execute`
|
|
2940
|
-
);
|
|
2941
|
-
}
|
|
2942
|
-
}
|
|
2943
|
-
if (sensorBindings && sensorBindings.length > 0) {
|
|
2944
|
-
await this.runIntentSensors(sensorBindings, intent, frame, "after", {
|
|
2945
|
-
decodedBody,
|
|
2946
|
-
effect
|
|
2947
|
-
});
|
|
2948
|
-
}
|
|
2949
|
-
}
|
|
2956
|
+
effect = await this.routeResolvedIntent(intent, frame);
|
|
2950
2957
|
await this.emitIntentObservers(observerBindings, {
|
|
2951
2958
|
event: "intent.completed",
|
|
2952
2959
|
timestamp: Date.now(),
|
|
@@ -2971,6 +2978,137 @@ var init_intent_router = __esm({
|
|
|
2971
2978
|
throw e;
|
|
2972
2979
|
}
|
|
2973
2980
|
}
|
|
2981
|
+
/**
|
|
2982
|
+
* Dispatches a resolved canonical intent to the correct execution path.
|
|
2983
|
+
* This keeps route() focused on observer/error lifecycle concerns.
|
|
2984
|
+
*/
|
|
2985
|
+
async routeResolvedIntent(intent, frame) {
|
|
2986
|
+
if (isChainExecIntent(intent)) {
|
|
2987
|
+
const chainRequest = this.parseChainRequestBody(frame.body);
|
|
2988
|
+
return this.executeChainRequest(frame, chainRequest);
|
|
2989
|
+
}
|
|
2990
|
+
if (isIntentExecIntent(intent)) {
|
|
2991
|
+
return this.routeIntentExec(frame);
|
|
2992
|
+
}
|
|
2993
|
+
if (this.handlers.has(intent)) {
|
|
2994
|
+
return this.routeRegisteredIntent(intent, frame);
|
|
2995
|
+
}
|
|
2996
|
+
const builtinEffect = routeSystemBuiltinIntent(
|
|
2997
|
+
intent,
|
|
2998
|
+
frame.body,
|
|
2999
|
+
this.encoder
|
|
3000
|
+
);
|
|
3001
|
+
if (builtinEffect) {
|
|
3002
|
+
if (intent === "system.ping" || intent === "public.ping") {
|
|
3003
|
+
this.logger.debug("PING received");
|
|
3004
|
+
}
|
|
3005
|
+
return builtinEffect;
|
|
3006
|
+
}
|
|
3007
|
+
return this.routeRegisteredIntent(intent, frame);
|
|
3008
|
+
}
|
|
3009
|
+
/**
|
|
3010
|
+
* Handles INTENT.EXEC by building an inner frame and routing it normally.
|
|
3011
|
+
* The recursive route call is intentional so sensors/observers/policies for
|
|
3012
|
+
* the inner intent stay identical to a direct request.
|
|
3013
|
+
*/
|
|
3014
|
+
async routeIntentExec(frame) {
|
|
3015
|
+
const execBody = this.parseIntentExecBody(frame.body);
|
|
3016
|
+
const innerIntent = execBody.intent;
|
|
3017
|
+
const innerArgs = execBody.args || {};
|
|
3018
|
+
if (!innerIntent) {
|
|
3019
|
+
throw new Error("INTENT.EXEC missing inner intent");
|
|
3020
|
+
}
|
|
3021
|
+
this.logger.debug(`EXEC: routing to inner intent '${innerIntent}'`);
|
|
3022
|
+
const innerHeaders = new Map(frame.headers);
|
|
3023
|
+
innerHeaders.set(TLV_INTENT, this.encoder.encode(innerIntent));
|
|
3024
|
+
const inlineCapsule = this.toInlineCapsuleRecord(execBody.capsule);
|
|
3025
|
+
const capsuleId = this.extractInlineCapsuleId(inlineCapsule);
|
|
3026
|
+
if (capsuleId) {
|
|
3027
|
+
innerHeaders.set(TLV_CAPSULE, this.encoder.encode(capsuleId));
|
|
3028
|
+
innerHeaders.set(TLV_PROOF_REF, this.encoder.encode(capsuleId));
|
|
3029
|
+
}
|
|
3030
|
+
const innerFrame = withAxisExecutionContext(
|
|
3031
|
+
{
|
|
3032
|
+
...frame,
|
|
3033
|
+
headers: innerHeaders,
|
|
3034
|
+
body: this.encodeJson(innerArgs)
|
|
3035
|
+
},
|
|
3036
|
+
mergeAxisExecutionContext(getAxisExecutionContext(frame), {
|
|
3037
|
+
metaIntent: "INTENT.EXEC",
|
|
3038
|
+
actorId: this.getActorIdFromFrame(frame),
|
|
3039
|
+
inlineCapsule
|
|
3040
|
+
}) || {}
|
|
3041
|
+
);
|
|
3042
|
+
return this.route(innerFrame);
|
|
3043
|
+
}
|
|
3044
|
+
/**
|
|
3045
|
+
* Executes an app-registered intent: before sensors, body decode, capsule
|
|
3046
|
+
* policy, handler invocation, then after sensors.
|
|
3047
|
+
*/
|
|
3048
|
+
async routeRegisteredIntent(intent, frame) {
|
|
3049
|
+
const handler = this.handlers.get(intent);
|
|
3050
|
+
if (!handler) {
|
|
3051
|
+
throw new Error(`Intent not found: ${intent}`);
|
|
3052
|
+
}
|
|
3053
|
+
const sensorBindings = this.intentSensors.get(intent);
|
|
3054
|
+
if (sensorBindings && sensorBindings.length > 0) {
|
|
3055
|
+
await this.runIntentSensors(sensorBindings, intent, frame, "before");
|
|
3056
|
+
}
|
|
3057
|
+
const decoder = this.intentDecoders.get(intent);
|
|
3058
|
+
const decodedBody = this.decodeIntentBody(intent, frame, decoder);
|
|
3059
|
+
this.enforceCapsulePolicy(
|
|
3060
|
+
intent,
|
|
3061
|
+
frame,
|
|
3062
|
+
decodedBody,
|
|
3063
|
+
this.getEffectiveCapsulePolicy(intent, frame)
|
|
3064
|
+
);
|
|
3065
|
+
const effect = await this.invokeRegisteredHandler(
|
|
3066
|
+
intent,
|
|
3067
|
+
handler,
|
|
3068
|
+
frame,
|
|
3069
|
+
decoder,
|
|
3070
|
+
decodedBody
|
|
3071
|
+
);
|
|
3072
|
+
if (sensorBindings && sensorBindings.length > 0) {
|
|
3073
|
+
await this.runIntentSensors(sensorBindings, intent, frame, "after", {
|
|
3074
|
+
decodedBody,
|
|
3075
|
+
effect
|
|
3076
|
+
});
|
|
3077
|
+
}
|
|
3078
|
+
return effect;
|
|
3079
|
+
}
|
|
3080
|
+
decodeIntentBody(intent, frame, decoder) {
|
|
3081
|
+
if (!decoder) return frame.body;
|
|
3082
|
+
try {
|
|
3083
|
+
return decoder(Buffer.from(frame.body));
|
|
3084
|
+
} catch (decodeErr) {
|
|
3085
|
+
throw new Error(
|
|
3086
|
+
`IntentBody decode failed for ${intent}: ${decodeErr.message}`
|
|
3087
|
+
);
|
|
3088
|
+
}
|
|
3089
|
+
}
|
|
3090
|
+
async invokeRegisteredHandler(intent, handler, frame, decoder, decodedBody) {
|
|
3091
|
+
if (typeof handler === "function") {
|
|
3092
|
+
const resultBody = decoder ? await handler(decodedBody, frame.headers) : await handler(frame.body, frame.headers);
|
|
3093
|
+
return {
|
|
3094
|
+
ok: true,
|
|
3095
|
+
effect: "complete",
|
|
3096
|
+
body: resultBody
|
|
3097
|
+
};
|
|
3098
|
+
}
|
|
3099
|
+
if (typeof handler.handle === "function") {
|
|
3100
|
+
return handler.handle(frame);
|
|
3101
|
+
}
|
|
3102
|
+
if (typeof handler.execute === "function") {
|
|
3103
|
+
const bodyRes = decoder ? await handler.execute(decodedBody, frame.headers) : await handler.execute(frame.body, frame.headers);
|
|
3104
|
+
return {
|
|
3105
|
+
ok: true,
|
|
3106
|
+
effect: "complete",
|
|
3107
|
+
body: bodyRes
|
|
3108
|
+
};
|
|
3109
|
+
}
|
|
3110
|
+
throw new Error(`Handler for ${intent} does not implement handle or execute`);
|
|
3111
|
+
}
|
|
2974
3112
|
logIntent(intent, start, ok, error) {
|
|
2975
3113
|
const diff = process.hrtime(start);
|
|
2976
3114
|
const ms = (diff[0] * 1e3 + diff[1] / 1e6).toFixed(2);
|
|
@@ -3064,62 +3202,9 @@ var init_intent_router = __esm({
|
|
|
3064
3202
|
if (contract) {
|
|
3065
3203
|
this.intentContracts.set(intent, contract);
|
|
3066
3204
|
}
|
|
3067
|
-
const
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
methodName
|
|
3071
|
-
);
|
|
3072
|
-
const classProof = Reflect.getMetadata(
|
|
3073
|
-
REQUIRED_PROOF_METADATA_KEY,
|
|
3074
|
-
proto.constructor
|
|
3075
|
-
);
|
|
3076
|
-
const isPublicMethod = Reflect.getMetadata(
|
|
3077
|
-
AXIS_PUBLIC_KEY,
|
|
3078
|
-
proto,
|
|
3079
|
-
methodName
|
|
3080
|
-
);
|
|
3081
|
-
const isPublicClass = Reflect.getMetadata(
|
|
3082
|
-
AXIS_PUBLIC_KEY,
|
|
3083
|
-
proto.constructor
|
|
3084
|
-
);
|
|
3085
|
-
const isAnonMethod = Reflect.getMetadata(
|
|
3086
|
-
AXIS_ANONYMOUS_KEY,
|
|
3087
|
-
proto,
|
|
3088
|
-
methodName
|
|
3089
|
-
);
|
|
3090
|
-
const isAnonClass = Reflect.getMetadata(
|
|
3091
|
-
AXIS_ANONYMOUS_KEY,
|
|
3092
|
-
proto.constructor
|
|
3093
|
-
);
|
|
3094
|
-
const isAuthorizedMethod = Reflect.getMetadata(
|
|
3095
|
-
AXIS_AUTHORIZED_KEY,
|
|
3096
|
-
proto,
|
|
3097
|
-
methodName
|
|
3098
|
-
);
|
|
3099
|
-
const isAuthorizedClass = Reflect.getMetadata(
|
|
3100
|
-
AXIS_AUTHORIZED_KEY,
|
|
3101
|
-
proto.constructor
|
|
3102
|
-
);
|
|
3103
|
-
const methodPolicyProof = mergeProofKinds(
|
|
3104
|
-
methodProof,
|
|
3105
|
-
accessProofKinds(isPublicMethod, isAnonMethod, isAuthorizedMethod)
|
|
3106
|
-
);
|
|
3107
|
-
const classPolicyProof = mergeProofKinds(
|
|
3108
|
-
classProof,
|
|
3109
|
-
accessProofKinds(isPublicClass, isAnonClass, isAuthorizedClass)
|
|
3110
|
-
);
|
|
3111
|
-
const requiredProof = methodPolicyProof.length ? methodPolicyProof : classPolicyProof;
|
|
3112
|
-
if (requiredProof.length > 0) {
|
|
3113
|
-
this.intentRequiredProof.set(intent, requiredProof);
|
|
3114
|
-
}
|
|
3115
|
-
if (requiredProof.includes("NONE")) {
|
|
3116
|
-
this.publicIntents.add(intent);
|
|
3117
|
-
}
|
|
3118
|
-
if (requiredProof.includes("ANONYMOUS")) {
|
|
3119
|
-
this.anonymousIntents.add(intent);
|
|
3120
|
-
}
|
|
3121
|
-
if (requiredProof.includes("AUTHORIZED")) {
|
|
3122
|
-
this.authorizedIntents.add(intent);
|
|
3205
|
+
const proofPolicy = resolveIntentProofPolicy(proto, methodName);
|
|
3206
|
+
if (proofPolicy.requiredProof.length > 0) {
|
|
3207
|
+
this.intentRequiredProof.set(intent, proofPolicy.requiredProof);
|
|
3123
3208
|
}
|
|
3124
3209
|
const rateLimit = Reflect.getMetadata(
|
|
3125
3210
|
AXIS_RATE_LIMIT_KEY,
|
|
@@ -3141,13 +3226,13 @@ var init_intent_router = __esm({
|
|
|
3141
3226
|
return this.intentRequiredProof.get(this.resolveIntentAlias(intent));
|
|
3142
3227
|
}
|
|
3143
3228
|
isPublic(intent) {
|
|
3144
|
-
return this.
|
|
3229
|
+
return this.getRequiredProof(intent)?.includes("NONE") ?? false;
|
|
3145
3230
|
}
|
|
3146
3231
|
isAnonymous(intent) {
|
|
3147
|
-
return this.
|
|
3232
|
+
return this.getRequiredProof(intent)?.includes("ANONYMOUS") ?? false;
|
|
3148
3233
|
}
|
|
3149
3234
|
isAuthorized(intent) {
|
|
3150
|
-
return this.
|
|
3235
|
+
return this.getRequiredProof(intent)?.includes("AUTHORIZED") ?? false;
|
|
3151
3236
|
}
|
|
3152
3237
|
getRateLimit(intent) {
|
|
3153
3238
|
return this.intentRateLimits.get(this.resolveIntentAlias(intent));
|
|
@@ -3168,7 +3253,7 @@ var init_intent_router = __esm({
|
|
|
3168
3253
|
}
|
|
3169
3254
|
/** The system/builtin intents (ping, time, echo, chain, intent.exec). */
|
|
3170
3255
|
getSystemIntents() {
|
|
3171
|
-
return [...
|
|
3256
|
+
return [...BUILTIN_INTENTS];
|
|
3172
3257
|
}
|
|
3173
3258
|
/** True if every intent in the handler is public, or any one is public — returns true if ANY intent is @AxisPublic. */
|
|
3174
3259
|
isHandlerPublic(handlerName) {
|
|
@@ -3241,7 +3326,7 @@ var init_intent_router = __esm({
|
|
|
3241
3326
|
* canonical intent. Existing exact intent names always win.
|
|
3242
3327
|
*/
|
|
3243
3328
|
resolveIntentAlias(intent) {
|
|
3244
|
-
if (this.handlers.has(intent) ||
|
|
3329
|
+
if (this.handlers.has(intent) || isBuiltinIntent(intent)) {
|
|
3245
3330
|
return intent;
|
|
3246
3331
|
}
|
|
3247
3332
|
const separator = "...";
|
|
@@ -3765,18 +3850,6 @@ var init_intent_router = __esm({
|
|
|
3765
3850
|
this.intentSchemas.set(meta.intent, schema);
|
|
3766
3851
|
}
|
|
3767
3852
|
};
|
|
3768
|
-
/** Intents handled inline in route() — not in `handlers` map */
|
|
3769
|
-
_IntentRouter.BUILTIN_INTENTS = /* @__PURE__ */ new Set([
|
|
3770
|
-
"system.ping",
|
|
3771
|
-
"public.ping",
|
|
3772
|
-
"system.time",
|
|
3773
|
-
"system.echo",
|
|
3774
|
-
"CHAIN.EXEC",
|
|
3775
|
-
"axis.chain.exec",
|
|
3776
|
-
"INTENT.EXEC",
|
|
3777
|
-
"axis.intent.exec"
|
|
3778
|
-
]);
|
|
3779
|
-
IntentRouter = _IntentRouter;
|
|
3780
3853
|
}
|
|
3781
3854
|
});
|
|
3782
3855
|
|