@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.js
CHANGED
|
@@ -2293,20 +2293,70 @@ var init_axis_error = __esm({
|
|
|
2293
2293
|
}
|
|
2294
2294
|
});
|
|
2295
2295
|
|
|
2296
|
-
// src/engine/intent.
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
IntentRouter: () => IntentRouter
|
|
2300
|
-
});
|
|
2301
|
-
function observerRefKey(ref) {
|
|
2302
|
-
return typeof ref === "string" ? ref : ref.name;
|
|
2296
|
+
// src/engine/intent-builtins.ts
|
|
2297
|
+
function isBuiltinIntent(intent) {
|
|
2298
|
+
return BUILTIN_INTENTS.has(intent);
|
|
2303
2299
|
}
|
|
2304
|
-
function
|
|
2305
|
-
return
|
|
2300
|
+
function isChainExecIntent(intent) {
|
|
2301
|
+
return intent === "CHAIN.EXEC" || intent === "axis.chain.exec";
|
|
2306
2302
|
}
|
|
2307
|
-
function
|
|
2308
|
-
return
|
|
2303
|
+
function isIntentExecIntent(intent) {
|
|
2304
|
+
return intent === "INTENT.EXEC" || intent === "axis.intent.exec";
|
|
2309
2305
|
}
|
|
2306
|
+
function routeSystemBuiltinIntent(intent, body, encoder) {
|
|
2307
|
+
if (intent === "system.ping" || intent === "public.ping") {
|
|
2308
|
+
return {
|
|
2309
|
+
ok: true,
|
|
2310
|
+
effect: "pong",
|
|
2311
|
+
headers: /* @__PURE__ */ new Map([[100, encoder.encode("AXIS_BACKEND_V1")]]),
|
|
2312
|
+
body: encoder.encode(
|
|
2313
|
+
JSON.stringify({
|
|
2314
|
+
status: "ok",
|
|
2315
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2316
|
+
version: "1.0.0"
|
|
2317
|
+
})
|
|
2318
|
+
)
|
|
2319
|
+
};
|
|
2320
|
+
}
|
|
2321
|
+
if (intent === "system.time") {
|
|
2322
|
+
const ts = Date.now().toString();
|
|
2323
|
+
return {
|
|
2324
|
+
ok: true,
|
|
2325
|
+
effect: "time",
|
|
2326
|
+
body: encoder.encode(
|
|
2327
|
+
JSON.stringify({
|
|
2328
|
+
ts,
|
|
2329
|
+
iso: (/* @__PURE__ */ new Date()).toISOString()
|
|
2330
|
+
})
|
|
2331
|
+
)
|
|
2332
|
+
};
|
|
2333
|
+
}
|
|
2334
|
+
if (intent === "system.echo") {
|
|
2335
|
+
return {
|
|
2336
|
+
ok: true,
|
|
2337
|
+
effect: "echo",
|
|
2338
|
+
body
|
|
2339
|
+
};
|
|
2340
|
+
}
|
|
2341
|
+
return void 0;
|
|
2342
|
+
}
|
|
2343
|
+
var BUILTIN_INTENTS;
|
|
2344
|
+
var init_intent_builtins = __esm({
|
|
2345
|
+
"src/engine/intent-builtins.ts"() {
|
|
2346
|
+
BUILTIN_INTENTS = /* @__PURE__ */ new Set([
|
|
2347
|
+
"system.ping",
|
|
2348
|
+
"public.ping",
|
|
2349
|
+
"system.time",
|
|
2350
|
+
"system.echo",
|
|
2351
|
+
"CHAIN.EXEC",
|
|
2352
|
+
"axis.chain.exec",
|
|
2353
|
+
"INTENT.EXEC",
|
|
2354
|
+
"axis.intent.exec"
|
|
2355
|
+
]);
|
|
2356
|
+
}
|
|
2357
|
+
});
|
|
2358
|
+
|
|
2359
|
+
// src/engine/intent-proof-policy.ts
|
|
2310
2360
|
function mergeProofKinds(...proofGroups) {
|
|
2311
2361
|
const merged = /* @__PURE__ */ new Set();
|
|
2312
2362
|
for (const proofs of proofGroups) {
|
|
@@ -2323,6 +2373,81 @@ function accessProofKinds(isPublic, isAnonymous, isAuthorized) {
|
|
|
2323
2373
|
if (isAuthorized) proofs.push("AUTHORIZED");
|
|
2324
2374
|
return proofs;
|
|
2325
2375
|
}
|
|
2376
|
+
function resolveIntentProofPolicy(proto, methodName) {
|
|
2377
|
+
const methodProof = Reflect.getMetadata(
|
|
2378
|
+
REQUIRED_PROOF_METADATA_KEY,
|
|
2379
|
+
proto,
|
|
2380
|
+
methodName
|
|
2381
|
+
);
|
|
2382
|
+
const classProof = Reflect.getMetadata(
|
|
2383
|
+
REQUIRED_PROOF_METADATA_KEY,
|
|
2384
|
+
proto.constructor
|
|
2385
|
+
);
|
|
2386
|
+
const isPublicMethod = Reflect.getMetadata(
|
|
2387
|
+
AXIS_PUBLIC_KEY,
|
|
2388
|
+
proto,
|
|
2389
|
+
methodName
|
|
2390
|
+
);
|
|
2391
|
+
const isPublicClass = Reflect.getMetadata(
|
|
2392
|
+
AXIS_PUBLIC_KEY,
|
|
2393
|
+
proto.constructor
|
|
2394
|
+
);
|
|
2395
|
+
const isAnonymousMethod = Reflect.getMetadata(
|
|
2396
|
+
AXIS_ANONYMOUS_KEY,
|
|
2397
|
+
proto,
|
|
2398
|
+
methodName
|
|
2399
|
+
);
|
|
2400
|
+
const isAnonymousClass = Reflect.getMetadata(
|
|
2401
|
+
AXIS_ANONYMOUS_KEY,
|
|
2402
|
+
proto.constructor
|
|
2403
|
+
);
|
|
2404
|
+
const isAuthorizedMethod = Reflect.getMetadata(
|
|
2405
|
+
AXIS_AUTHORIZED_KEY,
|
|
2406
|
+
proto,
|
|
2407
|
+
methodName
|
|
2408
|
+
);
|
|
2409
|
+
const isAuthorizedClass = Reflect.getMetadata(
|
|
2410
|
+
AXIS_AUTHORIZED_KEY,
|
|
2411
|
+
proto.constructor
|
|
2412
|
+
);
|
|
2413
|
+
const methodPolicyProof = mergeProofKinds(
|
|
2414
|
+
methodProof,
|
|
2415
|
+
accessProofKinds(isPublicMethod, isAnonymousMethod, isAuthorizedMethod)
|
|
2416
|
+
);
|
|
2417
|
+
const classPolicyProof = mergeProofKinds(
|
|
2418
|
+
classProof,
|
|
2419
|
+
accessProofKinds(isPublicClass, isAnonymousClass, isAuthorizedClass)
|
|
2420
|
+
);
|
|
2421
|
+
const requiredProof = methodPolicyProof.length ? methodPolicyProof : classPolicyProof;
|
|
2422
|
+
return {
|
|
2423
|
+
requiredProof,
|
|
2424
|
+
isPublic: requiredProof.includes("NONE"),
|
|
2425
|
+
isAnonymous: requiredProof.includes("ANONYMOUS"),
|
|
2426
|
+
isAuthorized: requiredProof.includes("AUTHORIZED")
|
|
2427
|
+
};
|
|
2428
|
+
}
|
|
2429
|
+
var import_reflect_metadata12;
|
|
2430
|
+
var init_intent_proof_policy = __esm({
|
|
2431
|
+
"src/engine/intent-proof-policy.ts"() {
|
|
2432
|
+
import_reflect_metadata12 = require("reflect-metadata");
|
|
2433
|
+
init_intent_policy_decorator();
|
|
2434
|
+
}
|
|
2435
|
+
});
|
|
2436
|
+
|
|
2437
|
+
// src/engine/intent.router.ts
|
|
2438
|
+
var intent_router_exports = {};
|
|
2439
|
+
__export(intent_router_exports, {
|
|
2440
|
+
IntentRouter: () => IntentRouter
|
|
2441
|
+
});
|
|
2442
|
+
function observerRefKey(ref) {
|
|
2443
|
+
return typeof ref === "string" ? ref : ref.name;
|
|
2444
|
+
}
|
|
2445
|
+
function sensorRefKey(ref) {
|
|
2446
|
+
return typeof ref === "string" ? ref : ref.name;
|
|
2447
|
+
}
|
|
2448
|
+
function sensorBindingKey(binding) {
|
|
2449
|
+
return `${binding.when}:${sensorRefKey(binding.ref)}`;
|
|
2450
|
+
}
|
|
2326
2451
|
function mergeIntentSensorBindings(...sensorGroups) {
|
|
2327
2452
|
const merged = /* @__PURE__ */ new Map();
|
|
2328
2453
|
for (const group of sensorGroups) {
|
|
@@ -2378,7 +2503,7 @@ function normalizeChainConfig(decoratorConfig, intentConfig) {
|
|
|
2378
2503
|
...intentConfig
|
|
2379
2504
|
};
|
|
2380
2505
|
}
|
|
2381
|
-
var import_axis_protocol3, import_dto_schema,
|
|
2506
|
+
var import_axis_protocol3, import_dto_schema, IntentRouter;
|
|
2382
2507
|
var init_intent_router = __esm({
|
|
2383
2508
|
"src/engine/intent.router.ts"() {
|
|
2384
2509
|
import_axis_protocol3 = require("@nextera.one/axis-protocol");
|
|
@@ -2399,7 +2524,9 @@ var init_intent_router = __esm({
|
|
|
2399
2524
|
init_cce_pipeline();
|
|
2400
2525
|
init_axis_error();
|
|
2401
2526
|
init_constants();
|
|
2402
|
-
|
|
2527
|
+
init_intent_builtins();
|
|
2528
|
+
init_intent_proof_policy();
|
|
2529
|
+
IntentRouter = class _IntentRouter {
|
|
2403
2530
|
constructor(dependencyResolver, observerDispatcher, sensorRegistry) {
|
|
2404
2531
|
this.logger = createAxisLogger(_IntentRouter.name);
|
|
2405
2532
|
this.decoder = new TextDecoder();
|
|
@@ -2430,12 +2557,6 @@ var init_intent_router = __esm({
|
|
|
2430
2557
|
this.intentContracts = /* @__PURE__ */ new Map();
|
|
2431
2558
|
/** Per-intent required proof kinds */
|
|
2432
2559
|
this.intentRequiredProof = /* @__PURE__ */ new Map();
|
|
2433
|
-
/** Intents flagged as public (no auth required) */
|
|
2434
|
-
this.publicIntents = /* @__PURE__ */ new Set();
|
|
2435
|
-
/** Intents flagged as anonymous-session accessible */
|
|
2436
|
-
this.anonymousIntents = /* @__PURE__ */ new Set();
|
|
2437
|
-
/** Intents flagged as authorized-session accessible */
|
|
2438
|
-
this.authorizedIntents = /* @__PURE__ */ new Set();
|
|
2439
2560
|
/** Per-intent rate limit config */
|
|
2440
2561
|
this.intentRateLimits = /* @__PURE__ */ new Map();
|
|
2441
2562
|
/** CCE handler registry */
|
|
@@ -2466,10 +2587,10 @@ var init_intent_router = __esm({
|
|
|
2466
2587
|
}
|
|
2467
2588
|
has(intent) {
|
|
2468
2589
|
const resolved = this.resolveIntentAlias(intent);
|
|
2469
|
-
return this.handlers.has(resolved) ||
|
|
2590
|
+
return this.handlers.has(resolved) || isBuiltinIntent(resolved);
|
|
2470
2591
|
}
|
|
2471
2592
|
getRegisteredIntents() {
|
|
2472
|
-
return [...
|
|
2593
|
+
return [...BUILTIN_INTENTS, ...this.handlers.keys()];
|
|
2473
2594
|
}
|
|
2474
2595
|
getIntentEntry(intent) {
|
|
2475
2596
|
const resolved = this.resolveIntentAlias(intent);
|
|
@@ -2478,7 +2599,7 @@ var init_intent_router = __esm({
|
|
|
2478
2599
|
schema: this.intentSchemas.get(resolved),
|
|
2479
2600
|
validators: this.intentValidators.get(resolved),
|
|
2480
2601
|
hasSensors: this.intentSensors.has(resolved),
|
|
2481
|
-
builtin:
|
|
2602
|
+
builtin: isBuiltinIntent(resolved),
|
|
2482
2603
|
kind: this.intentKinds.get(resolved),
|
|
2483
2604
|
chain: this.intentChains.get(resolved),
|
|
2484
2605
|
capsulePolicy: this.intentCapsulePolicies.get(resolved),
|
|
@@ -2500,6 +2621,9 @@ var init_intent_router = __esm({
|
|
|
2500
2621
|
* @param {any} handler - The handler function or object
|
|
2501
2622
|
*/
|
|
2502
2623
|
register(intent, handler) {
|
|
2624
|
+
if (this.handlers.has(intent)) {
|
|
2625
|
+
this.logger.warn(`Intent ${intent} is already registered; replacing handler`);
|
|
2626
|
+
}
|
|
2503
2627
|
this.handlers.set(intent, handler);
|
|
2504
2628
|
if (typeof handler === "function" && handler.name) {
|
|
2505
2629
|
this.intentHandlerRefs.set(intent, handler.name);
|
|
@@ -2584,9 +2708,14 @@ var init_intent_router = __esm({
|
|
|
2584
2708
|
* Routes a decoded AXIS frame to the appropriate handler.
|
|
2585
2709
|
*
|
|
2586
2710
|
* **Precedence:**
|
|
2587
|
-
* 1.
|
|
2588
|
-
* 2.
|
|
2589
|
-
* 3.
|
|
2711
|
+
* 1. SDK meta-intents (`CHAIN.EXEC`, `INTENT.EXEC`)
|
|
2712
|
+
* 2. Dynamically registered handlers from modules
|
|
2713
|
+
* 3. Simple SDK built-in fallback (`system.ping`, `public.ping`, `system.time`, `system.echo`)
|
|
2714
|
+
*
|
|
2715
|
+
* Registered app handlers intentionally win over simple built-ins. This lets
|
|
2716
|
+
* applications attach sensors, rate limits, and custom responses to intents
|
|
2717
|
+
* like `system.ping` while keeping a default fallback for apps that do not
|
|
2718
|
+
* register their own handler.
|
|
2590
2719
|
*
|
|
2591
2720
|
* @param {AxisFrame} frame - The validated and decoded binary frame
|
|
2592
2721
|
* @returns {Promise<AxisEffect>} The resulting effect of the execution
|
|
@@ -2610,128 +2739,7 @@ var init_intent_router = __esm({
|
|
|
2610
2739
|
frame
|
|
2611
2740
|
});
|
|
2612
2741
|
let effect;
|
|
2613
|
-
|
|
2614
|
-
this.logger.debug("PING received");
|
|
2615
|
-
effect = {
|
|
2616
|
-
ok: true,
|
|
2617
|
-
effect: "pong",
|
|
2618
|
-
headers: /* @__PURE__ */ new Map([
|
|
2619
|
-
[100, new TextEncoder().encode("AXIS_BACKEND_V1")]
|
|
2620
|
-
]),
|
|
2621
|
-
body: new TextEncoder().encode(
|
|
2622
|
-
JSON.stringify({
|
|
2623
|
-
status: "ok",
|
|
2624
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2625
|
-
version: "1.0.0"
|
|
2626
|
-
})
|
|
2627
|
-
)
|
|
2628
|
-
};
|
|
2629
|
-
} else if (intent === "system.time") {
|
|
2630
|
-
const ts = Date.now().toString();
|
|
2631
|
-
effect = {
|
|
2632
|
-
ok: true,
|
|
2633
|
-
effect: "time",
|
|
2634
|
-
body: new TextEncoder().encode(
|
|
2635
|
-
JSON.stringify({
|
|
2636
|
-
ts,
|
|
2637
|
-
iso: (/* @__PURE__ */ new Date()).toISOString()
|
|
2638
|
-
})
|
|
2639
|
-
)
|
|
2640
|
-
};
|
|
2641
|
-
} else if (intent === "system.echo") {
|
|
2642
|
-
effect = {
|
|
2643
|
-
ok: true,
|
|
2644
|
-
effect: "echo",
|
|
2645
|
-
body: frame.body
|
|
2646
|
-
};
|
|
2647
|
-
} else if (intent === "CHAIN.EXEC" || intent === "axis.chain.exec") {
|
|
2648
|
-
const chainRequest = this.parseChainRequestBody(frame.body);
|
|
2649
|
-
effect = await this.executeChainRequest(frame, chainRequest);
|
|
2650
|
-
} else if (intent === "INTENT.EXEC" || intent === "axis.intent.exec") {
|
|
2651
|
-
const execBody = this.parseIntentExecBody(frame.body);
|
|
2652
|
-
const innerIntent = execBody.intent;
|
|
2653
|
-
const innerArgs = execBody.args || {};
|
|
2654
|
-
if (!innerIntent) {
|
|
2655
|
-
throw new Error("INTENT.EXEC missing inner intent");
|
|
2656
|
-
}
|
|
2657
|
-
this.logger.debug(`EXEC: routing to inner intent '${innerIntent}'`);
|
|
2658
|
-
const innerHeaders = new Map(frame.headers);
|
|
2659
|
-
innerHeaders.set(import_axis_protocol2.TLV_INTENT, this.encoder.encode(innerIntent));
|
|
2660
|
-
const inlineCapsule = this.toInlineCapsuleRecord(execBody.capsule);
|
|
2661
|
-
const capsuleId = this.extractInlineCapsuleId(inlineCapsule);
|
|
2662
|
-
if (capsuleId) {
|
|
2663
|
-
innerHeaders.set(import_axis_protocol2.TLV_CAPSULE, this.encoder.encode(capsuleId));
|
|
2664
|
-
innerHeaders.set(import_axis_protocol2.TLV_PROOF_REF, this.encoder.encode(capsuleId));
|
|
2665
|
-
}
|
|
2666
|
-
const innerFrame = withAxisExecutionContext(
|
|
2667
|
-
{
|
|
2668
|
-
...frame,
|
|
2669
|
-
headers: innerHeaders,
|
|
2670
|
-
body: this.encodeJson(innerArgs)
|
|
2671
|
-
},
|
|
2672
|
-
mergeAxisExecutionContext(getAxisExecutionContext(frame), {
|
|
2673
|
-
metaIntent: "INTENT.EXEC",
|
|
2674
|
-
actorId: this.getActorIdFromFrame(frame),
|
|
2675
|
-
inlineCapsule
|
|
2676
|
-
}) || {}
|
|
2677
|
-
);
|
|
2678
|
-
effect = await this.route(innerFrame);
|
|
2679
|
-
} else {
|
|
2680
|
-
const handler = this.handlers.get(intent);
|
|
2681
|
-
if (!handler) {
|
|
2682
|
-
throw new Error(`Intent not found: ${intent}`);
|
|
2683
|
-
}
|
|
2684
|
-
const sensorBindings = this.intentSensors.get(intent);
|
|
2685
|
-
if (sensorBindings && sensorBindings.length > 0) {
|
|
2686
|
-
await this.runIntentSensors(sensorBindings, intent, frame, "before");
|
|
2687
|
-
}
|
|
2688
|
-
const decoder = this.intentDecoders.get(intent);
|
|
2689
|
-
let decodedBody = frame.body;
|
|
2690
|
-
if (decoder) {
|
|
2691
|
-
try {
|
|
2692
|
-
decodedBody = decoder(Buffer.from(frame.body));
|
|
2693
|
-
} catch (decodeErr) {
|
|
2694
|
-
throw new Error(
|
|
2695
|
-
`IntentBody decode failed for ${intent}: ${decodeErr.message}`
|
|
2696
|
-
);
|
|
2697
|
-
}
|
|
2698
|
-
}
|
|
2699
|
-
this.enforceCapsulePolicy(
|
|
2700
|
-
intent,
|
|
2701
|
-
frame,
|
|
2702
|
-
decodedBody,
|
|
2703
|
-
this.getEffectiveCapsulePolicy(intent, frame)
|
|
2704
|
-
);
|
|
2705
|
-
if (typeof handler === "function") {
|
|
2706
|
-
const resultBody = decoder ? await handler(decodedBody, frame.headers) : await handler(frame.body, frame.headers);
|
|
2707
|
-
effect = {
|
|
2708
|
-
ok: true,
|
|
2709
|
-
effect: "complete",
|
|
2710
|
-
body: resultBody
|
|
2711
|
-
};
|
|
2712
|
-
} else {
|
|
2713
|
-
if (typeof handler.handle === "function") {
|
|
2714
|
-
effect = await handler.handle(frame);
|
|
2715
|
-
} else if (typeof handler.execute === "function") {
|
|
2716
|
-
const bodyRes = decoder ? await handler.execute(decodedBody, frame.headers) : await handler.execute(frame.body, frame.headers);
|
|
2717
|
-
effect = {
|
|
2718
|
-
ok: true,
|
|
2719
|
-
effect: "complete",
|
|
2720
|
-
body: bodyRes
|
|
2721
|
-
};
|
|
2722
|
-
} else {
|
|
2723
|
-
throw new Error(
|
|
2724
|
-
`Handler for ${intent} does not implement handle or execute`
|
|
2725
|
-
);
|
|
2726
|
-
}
|
|
2727
|
-
}
|
|
2728
|
-
if (sensorBindings && sensorBindings.length > 0) {
|
|
2729
|
-
await this.runIntentSensors(sensorBindings, intent, frame, "after", {
|
|
2730
|
-
decodedBody,
|
|
2731
|
-
effect
|
|
2732
|
-
});
|
|
2733
|
-
}
|
|
2734
|
-
}
|
|
2742
|
+
effect = await this.routeResolvedIntent(intent, frame);
|
|
2735
2743
|
await this.emitIntentObservers(observerBindings, {
|
|
2736
2744
|
event: "intent.completed",
|
|
2737
2745
|
timestamp: Date.now(),
|
|
@@ -2756,6 +2764,137 @@ var init_intent_router = __esm({
|
|
|
2756
2764
|
throw e;
|
|
2757
2765
|
}
|
|
2758
2766
|
}
|
|
2767
|
+
/**
|
|
2768
|
+
* Dispatches a resolved canonical intent to the correct execution path.
|
|
2769
|
+
* This keeps route() focused on observer/error lifecycle concerns.
|
|
2770
|
+
*/
|
|
2771
|
+
async routeResolvedIntent(intent, frame) {
|
|
2772
|
+
if (isChainExecIntent(intent)) {
|
|
2773
|
+
const chainRequest = this.parseChainRequestBody(frame.body);
|
|
2774
|
+
return this.executeChainRequest(frame, chainRequest);
|
|
2775
|
+
}
|
|
2776
|
+
if (isIntentExecIntent(intent)) {
|
|
2777
|
+
return this.routeIntentExec(frame);
|
|
2778
|
+
}
|
|
2779
|
+
if (this.handlers.has(intent)) {
|
|
2780
|
+
return this.routeRegisteredIntent(intent, frame);
|
|
2781
|
+
}
|
|
2782
|
+
const builtinEffect = routeSystemBuiltinIntent(
|
|
2783
|
+
intent,
|
|
2784
|
+
frame.body,
|
|
2785
|
+
this.encoder
|
|
2786
|
+
);
|
|
2787
|
+
if (builtinEffect) {
|
|
2788
|
+
if (intent === "system.ping" || intent === "public.ping") {
|
|
2789
|
+
this.logger.debug("PING received");
|
|
2790
|
+
}
|
|
2791
|
+
return builtinEffect;
|
|
2792
|
+
}
|
|
2793
|
+
return this.routeRegisteredIntent(intent, frame);
|
|
2794
|
+
}
|
|
2795
|
+
/**
|
|
2796
|
+
* Handles INTENT.EXEC by building an inner frame and routing it normally.
|
|
2797
|
+
* The recursive route call is intentional so sensors/observers/policies for
|
|
2798
|
+
* the inner intent stay identical to a direct request.
|
|
2799
|
+
*/
|
|
2800
|
+
async routeIntentExec(frame) {
|
|
2801
|
+
const execBody = this.parseIntentExecBody(frame.body);
|
|
2802
|
+
const innerIntent = execBody.intent;
|
|
2803
|
+
const innerArgs = execBody.args || {};
|
|
2804
|
+
if (!innerIntent) {
|
|
2805
|
+
throw new Error("INTENT.EXEC missing inner intent");
|
|
2806
|
+
}
|
|
2807
|
+
this.logger.debug(`EXEC: routing to inner intent '${innerIntent}'`);
|
|
2808
|
+
const innerHeaders = new Map(frame.headers);
|
|
2809
|
+
innerHeaders.set(import_axis_protocol2.TLV_INTENT, this.encoder.encode(innerIntent));
|
|
2810
|
+
const inlineCapsule = this.toInlineCapsuleRecord(execBody.capsule);
|
|
2811
|
+
const capsuleId = this.extractInlineCapsuleId(inlineCapsule);
|
|
2812
|
+
if (capsuleId) {
|
|
2813
|
+
innerHeaders.set(import_axis_protocol2.TLV_CAPSULE, this.encoder.encode(capsuleId));
|
|
2814
|
+
innerHeaders.set(import_axis_protocol2.TLV_PROOF_REF, this.encoder.encode(capsuleId));
|
|
2815
|
+
}
|
|
2816
|
+
const innerFrame = withAxisExecutionContext(
|
|
2817
|
+
{
|
|
2818
|
+
...frame,
|
|
2819
|
+
headers: innerHeaders,
|
|
2820
|
+
body: this.encodeJson(innerArgs)
|
|
2821
|
+
},
|
|
2822
|
+
mergeAxisExecutionContext(getAxisExecutionContext(frame), {
|
|
2823
|
+
metaIntent: "INTENT.EXEC",
|
|
2824
|
+
actorId: this.getActorIdFromFrame(frame),
|
|
2825
|
+
inlineCapsule
|
|
2826
|
+
}) || {}
|
|
2827
|
+
);
|
|
2828
|
+
return this.route(innerFrame);
|
|
2829
|
+
}
|
|
2830
|
+
/**
|
|
2831
|
+
* Executes an app-registered intent: before sensors, body decode, capsule
|
|
2832
|
+
* policy, handler invocation, then after sensors.
|
|
2833
|
+
*/
|
|
2834
|
+
async routeRegisteredIntent(intent, frame) {
|
|
2835
|
+
const handler = this.handlers.get(intent);
|
|
2836
|
+
if (!handler) {
|
|
2837
|
+
throw new Error(`Intent not found: ${intent}`);
|
|
2838
|
+
}
|
|
2839
|
+
const sensorBindings = this.intentSensors.get(intent);
|
|
2840
|
+
if (sensorBindings && sensorBindings.length > 0) {
|
|
2841
|
+
await this.runIntentSensors(sensorBindings, intent, frame, "before");
|
|
2842
|
+
}
|
|
2843
|
+
const decoder = this.intentDecoders.get(intent);
|
|
2844
|
+
const decodedBody = this.decodeIntentBody(intent, frame, decoder);
|
|
2845
|
+
this.enforceCapsulePolicy(
|
|
2846
|
+
intent,
|
|
2847
|
+
frame,
|
|
2848
|
+
decodedBody,
|
|
2849
|
+
this.getEffectiveCapsulePolicy(intent, frame)
|
|
2850
|
+
);
|
|
2851
|
+
const effect = await this.invokeRegisteredHandler(
|
|
2852
|
+
intent,
|
|
2853
|
+
handler,
|
|
2854
|
+
frame,
|
|
2855
|
+
decoder,
|
|
2856
|
+
decodedBody
|
|
2857
|
+
);
|
|
2858
|
+
if (sensorBindings && sensorBindings.length > 0) {
|
|
2859
|
+
await this.runIntentSensors(sensorBindings, intent, frame, "after", {
|
|
2860
|
+
decodedBody,
|
|
2861
|
+
effect
|
|
2862
|
+
});
|
|
2863
|
+
}
|
|
2864
|
+
return effect;
|
|
2865
|
+
}
|
|
2866
|
+
decodeIntentBody(intent, frame, decoder) {
|
|
2867
|
+
if (!decoder) return frame.body;
|
|
2868
|
+
try {
|
|
2869
|
+
return decoder(Buffer.from(frame.body));
|
|
2870
|
+
} catch (decodeErr) {
|
|
2871
|
+
throw new Error(
|
|
2872
|
+
`IntentBody decode failed for ${intent}: ${decodeErr.message}`
|
|
2873
|
+
);
|
|
2874
|
+
}
|
|
2875
|
+
}
|
|
2876
|
+
async invokeRegisteredHandler(intent, handler, frame, decoder, decodedBody) {
|
|
2877
|
+
if (typeof handler === "function") {
|
|
2878
|
+
const resultBody = decoder ? await handler(decodedBody, frame.headers) : await handler(frame.body, frame.headers);
|
|
2879
|
+
return {
|
|
2880
|
+
ok: true,
|
|
2881
|
+
effect: "complete",
|
|
2882
|
+
body: resultBody
|
|
2883
|
+
};
|
|
2884
|
+
}
|
|
2885
|
+
if (typeof handler.handle === "function") {
|
|
2886
|
+
return handler.handle(frame);
|
|
2887
|
+
}
|
|
2888
|
+
if (typeof handler.execute === "function") {
|
|
2889
|
+
const bodyRes = decoder ? await handler.execute(decodedBody, frame.headers) : await handler.execute(frame.body, frame.headers);
|
|
2890
|
+
return {
|
|
2891
|
+
ok: true,
|
|
2892
|
+
effect: "complete",
|
|
2893
|
+
body: bodyRes
|
|
2894
|
+
};
|
|
2895
|
+
}
|
|
2896
|
+
throw new Error(`Handler for ${intent} does not implement handle or execute`);
|
|
2897
|
+
}
|
|
2759
2898
|
logIntent(intent, start, ok, error) {
|
|
2760
2899
|
const diff = process.hrtime(start);
|
|
2761
2900
|
const ms = (diff[0] * 1e3 + diff[1] / 1e6).toFixed(2);
|
|
@@ -2849,62 +2988,9 @@ var init_intent_router = __esm({
|
|
|
2849
2988
|
if (contract) {
|
|
2850
2989
|
this.intentContracts.set(intent, contract);
|
|
2851
2990
|
}
|
|
2852
|
-
const
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
methodName
|
|
2856
|
-
);
|
|
2857
|
-
const classProof = Reflect.getMetadata(
|
|
2858
|
-
REQUIRED_PROOF_METADATA_KEY,
|
|
2859
|
-
proto.constructor
|
|
2860
|
-
);
|
|
2861
|
-
const isPublicMethod = Reflect.getMetadata(
|
|
2862
|
-
AXIS_PUBLIC_KEY,
|
|
2863
|
-
proto,
|
|
2864
|
-
methodName
|
|
2865
|
-
);
|
|
2866
|
-
const isPublicClass = Reflect.getMetadata(
|
|
2867
|
-
AXIS_PUBLIC_KEY,
|
|
2868
|
-
proto.constructor
|
|
2869
|
-
);
|
|
2870
|
-
const isAnonMethod = Reflect.getMetadata(
|
|
2871
|
-
AXIS_ANONYMOUS_KEY,
|
|
2872
|
-
proto,
|
|
2873
|
-
methodName
|
|
2874
|
-
);
|
|
2875
|
-
const isAnonClass = Reflect.getMetadata(
|
|
2876
|
-
AXIS_ANONYMOUS_KEY,
|
|
2877
|
-
proto.constructor
|
|
2878
|
-
);
|
|
2879
|
-
const isAuthorizedMethod = Reflect.getMetadata(
|
|
2880
|
-
AXIS_AUTHORIZED_KEY,
|
|
2881
|
-
proto,
|
|
2882
|
-
methodName
|
|
2883
|
-
);
|
|
2884
|
-
const isAuthorizedClass = Reflect.getMetadata(
|
|
2885
|
-
AXIS_AUTHORIZED_KEY,
|
|
2886
|
-
proto.constructor
|
|
2887
|
-
);
|
|
2888
|
-
const methodPolicyProof = mergeProofKinds(
|
|
2889
|
-
methodProof,
|
|
2890
|
-
accessProofKinds(isPublicMethod, isAnonMethod, isAuthorizedMethod)
|
|
2891
|
-
);
|
|
2892
|
-
const classPolicyProof = mergeProofKinds(
|
|
2893
|
-
classProof,
|
|
2894
|
-
accessProofKinds(isPublicClass, isAnonClass, isAuthorizedClass)
|
|
2895
|
-
);
|
|
2896
|
-
const requiredProof = methodPolicyProof.length ? methodPolicyProof : classPolicyProof;
|
|
2897
|
-
if (requiredProof.length > 0) {
|
|
2898
|
-
this.intentRequiredProof.set(intent, requiredProof);
|
|
2899
|
-
}
|
|
2900
|
-
if (requiredProof.includes("NONE")) {
|
|
2901
|
-
this.publicIntents.add(intent);
|
|
2902
|
-
}
|
|
2903
|
-
if (requiredProof.includes("ANONYMOUS")) {
|
|
2904
|
-
this.anonymousIntents.add(intent);
|
|
2905
|
-
}
|
|
2906
|
-
if (requiredProof.includes("AUTHORIZED")) {
|
|
2907
|
-
this.authorizedIntents.add(intent);
|
|
2991
|
+
const proofPolicy = resolveIntentProofPolicy(proto, methodName);
|
|
2992
|
+
if (proofPolicy.requiredProof.length > 0) {
|
|
2993
|
+
this.intentRequiredProof.set(intent, proofPolicy.requiredProof);
|
|
2908
2994
|
}
|
|
2909
2995
|
const rateLimit = Reflect.getMetadata(
|
|
2910
2996
|
AXIS_RATE_LIMIT_KEY,
|
|
@@ -2926,13 +3012,13 @@ var init_intent_router = __esm({
|
|
|
2926
3012
|
return this.intentRequiredProof.get(this.resolveIntentAlias(intent));
|
|
2927
3013
|
}
|
|
2928
3014
|
isPublic(intent) {
|
|
2929
|
-
return this.
|
|
3015
|
+
return this.getRequiredProof(intent)?.includes("NONE") ?? false;
|
|
2930
3016
|
}
|
|
2931
3017
|
isAnonymous(intent) {
|
|
2932
|
-
return this.
|
|
3018
|
+
return this.getRequiredProof(intent)?.includes("ANONYMOUS") ?? false;
|
|
2933
3019
|
}
|
|
2934
3020
|
isAuthorized(intent) {
|
|
2935
|
-
return this.
|
|
3021
|
+
return this.getRequiredProof(intent)?.includes("AUTHORIZED") ?? false;
|
|
2936
3022
|
}
|
|
2937
3023
|
getRateLimit(intent) {
|
|
2938
3024
|
return this.intentRateLimits.get(this.resolveIntentAlias(intent));
|
|
@@ -2953,7 +3039,7 @@ var init_intent_router = __esm({
|
|
|
2953
3039
|
}
|
|
2954
3040
|
/** The system/builtin intents (ping, time, echo, chain, intent.exec). */
|
|
2955
3041
|
getSystemIntents() {
|
|
2956
|
-
return [...
|
|
3042
|
+
return [...BUILTIN_INTENTS];
|
|
2957
3043
|
}
|
|
2958
3044
|
/** True if every intent in the handler is public, or any one is public — returns true if ANY intent is @AxisPublic. */
|
|
2959
3045
|
isHandlerPublic(handlerName) {
|
|
@@ -3026,7 +3112,7 @@ var init_intent_router = __esm({
|
|
|
3026
3112
|
* canonical intent. Existing exact intent names always win.
|
|
3027
3113
|
*/
|
|
3028
3114
|
resolveIntentAlias(intent) {
|
|
3029
|
-
if (this.handlers.has(intent) ||
|
|
3115
|
+
if (this.handlers.has(intent) || isBuiltinIntent(intent)) {
|
|
3030
3116
|
return intent;
|
|
3031
3117
|
}
|
|
3032
3118
|
const separator = "...";
|
|
@@ -3550,18 +3636,6 @@ var init_intent_router = __esm({
|
|
|
3550
3636
|
this.intentSchemas.set(meta.intent, schema);
|
|
3551
3637
|
}
|
|
3552
3638
|
};
|
|
3553
|
-
/** Intents handled inline in route() — not in `handlers` map */
|
|
3554
|
-
_IntentRouter.BUILTIN_INTENTS = /* @__PURE__ */ new Set([
|
|
3555
|
-
"system.ping",
|
|
3556
|
-
"public.ping",
|
|
3557
|
-
"system.time",
|
|
3558
|
-
"system.echo",
|
|
3559
|
-
"CHAIN.EXEC",
|
|
3560
|
-
"axis.chain.exec",
|
|
3561
|
-
"INTENT.EXEC",
|
|
3562
|
-
"axis.intent.exec"
|
|
3563
|
-
]);
|
|
3564
|
-
IntentRouter = _IntentRouter;
|
|
3565
3639
|
}
|
|
3566
3640
|
});
|
|
3567
3641
|
|