@astrale-os/sdk 0.3.0 → 0.4.2
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/auth/compose.d.ts +2 -2
- package/dist/auth/compose.d.ts.map +1 -1
- package/dist/auth/compose.js +2 -2
- package/dist/auth/compose.js.map +1 -1
- package/dist/auth/function-context.d.ts +28 -0
- package/dist/auth/function-context.d.ts.map +1 -0
- package/dist/auth/function-context.js +47 -0
- package/dist/auth/function-context.js.map +1 -0
- package/dist/auth/index.d.ts +5 -3
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +3 -2
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/issuer-mint.d.ts +9 -9
- package/dist/auth/issuer-mint.d.ts.map +1 -1
- package/dist/auth/issuer-mint.js +3 -3
- package/dist/auth/issuer-mint.js.map +1 -1
- package/dist/auth/kernel-client.d.ts +5 -17
- package/dist/auth/kernel-client.d.ts.map +1 -1
- package/dist/auth/kernel-client.js +12 -34
- package/dist/auth/kernel-client.js.map +1 -1
- package/dist/cli/publish.js +1 -1
- package/dist/cli/publish.js.map +1 -1
- package/dist/config/define-domain.d.ts +1 -1
- package/dist/define/index.d.ts +1 -1
- package/dist/define/index.d.ts.map +1 -1
- package/dist/define/remote-function.d.ts +22 -30
- package/dist/define/remote-function.d.ts.map +1 -1
- package/dist/define/remote-function.js.map +1 -1
- package/dist/define/view.d.ts +6 -10
- package/dist/define/view.d.ts.map +1 -1
- package/dist/define/view.js.map +1 -1
- package/dist/dispatch/dispatcher.d.ts +1 -1
- package/dist/dispatch/dispatcher.d.ts.map +1 -1
- package/dist/dispatch/dispatcher.js +31 -7
- package/dist/dispatch/dispatcher.js.map +1 -1
- package/dist/dispatch/execute.d.ts +10 -6
- package/dist/dispatch/execute.d.ts.map +1 -1
- package/dist/dispatch/execute.js +5 -3
- package/dist/dispatch/execute.js.map +1 -1
- package/dist/dispatch/index.d.ts +0 -1
- package/dist/dispatch/index.d.ts.map +1 -1
- package/dist/dispatch/index.js +0 -1
- package/dist/dispatch/index.js.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/method/context.d.ts +34 -28
- package/dist/method/context.d.ts.map +1 -1
- package/dist/method/context.js +2 -1
- package/dist/method/context.js.map +1 -1
- package/dist/method/index.d.ts +1 -1
- package/dist/method/index.d.ts.map +1 -1
- package/dist/method/index.js.map +1 -1
- package/dist/method/single.d.ts +2 -2
- package/dist/method/single.d.ts.map +1 -1
- package/dist/server/auxiliary-routes.d.ts.map +1 -1
- package/dist/server/auxiliary-routes.js +40 -21
- package/dist/server/auxiliary-routes.js.map +1 -1
- package/dist/server/create.js +1 -1
- package/dist/server/create.js.map +1 -1
- package/dist/step/index.d.ts +5 -0
- package/dist/step/index.d.ts.map +1 -0
- package/dist/step/index.js +3 -0
- package/dist/step/index.js.map +1 -0
- package/dist/step/inline.d.ts +8 -0
- package/dist/step/inline.d.ts.map +1 -0
- package/dist/step/inline.js +22 -0
- package/dist/step/inline.js.map +1 -0
- package/dist/step/step.d.ts +28 -0
- package/dist/step/step.d.ts.map +1 -0
- package/dist/step/step.js +53 -0
- package/dist/step/step.js.map +1 -0
- package/package.json +5 -1
- package/src/auth/compose.ts +2 -2
- package/src/auth/function-context.ts +108 -0
- package/src/auth/index.ts +9 -3
- package/src/auth/issuer-mint.ts +10 -9
- package/src/auth/kernel-client.ts +19 -44
- package/src/cli/publish.ts +1 -1
- package/src/config/define-domain.ts +1 -1
- package/src/define/index.ts +1 -0
- package/src/define/remote-function.ts +34 -30
- package/src/define/view.ts +6 -10
- package/src/dispatch/dispatcher.ts +34 -8
- package/src/dispatch/execute.ts +15 -9
- package/src/dispatch/index.ts +0 -1
- package/src/index.ts +20 -5
- package/src/method/context.ts +50 -28
- package/src/method/index.ts +8 -1
- package/src/method/single.ts +2 -2
- package/src/server/auxiliary-routes.ts +41 -23
- package/src/server/create.ts +1 -1
- package/src/step/index.ts +4 -0
- package/src/step/inline.ts +38 -0
- package/src/step/step.ts +95 -0
- package/dist/deploy/hash-spec.d.ts +0 -9
- package/dist/deploy/hash-spec.d.ts.map +0 -1
- package/dist/deploy/hash-spec.js +0 -29
- package/dist/deploy/hash-spec.js.map +0 -1
- package/dist/dispatch/call-remote.d.ts +0 -39
- package/dist/dispatch/call-remote.d.ts.map +0 -1
- package/dist/dispatch/call-remote.js +0 -37
- package/dist/dispatch/call-remote.js.map +0 -1
- package/dist/domain/extend-core.d.ts +0 -49
- package/dist/domain/extend-core.d.ts.map +0 -1
- package/dist/domain/extend-core.js +0 -190
- package/dist/domain/extend-core.js.map +0 -1
- package/dist/server/worker-meta.d.ts +0 -6
- package/dist/server/worker-meta.d.ts.map +0 -1
- package/dist/server/worker-meta.js +0 -10
- package/dist/server/worker-meta.js.map +0 -1
- package/src/dispatch/call-remote.ts +0 -53
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
|
|
30
30
|
import type { RemoteIdentityConfig } from './identity'
|
|
31
31
|
|
|
32
|
-
import { buildComposedExpr, buildComposedGrant, buildSelfExpr
|
|
32
|
+
import { buildComposedExpr, buildComposedGrant, buildSelfExpr } from './compose'
|
|
33
33
|
import { signCredential } from './sign'
|
|
34
34
|
|
|
35
35
|
const DELEGATION_TTL_SECONDS = 3600
|
|
@@ -75,20 +75,6 @@ export async function bindKernel(
|
|
|
75
75
|
)
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
/**
|
|
79
|
-
* Build a `BoundClientSessionView` authenticated as the FUNCTION'S OWN
|
|
80
|
-
* identity — no inbound delegation, authority = the function's own grants
|
|
81
|
-
* only. The seam behind `selfKernel` for public/webhook handlers: an HMAC- or
|
|
82
|
-
* signature-verified webhook can act on the graph as itself after verifying
|
|
83
|
-
* the upstream. Next-hop mints delegate self only.
|
|
84
|
-
*/
|
|
85
|
-
export async function bindSelfKernel(
|
|
86
|
-
kernelUrl: string,
|
|
87
|
-
config: RemoteIdentityConfig,
|
|
88
|
-
): Promise<BoundClientSessionView<FnMap>> {
|
|
89
|
-
return bindSession(kernelUrl, config, buildSelfGrant().grant, () => buildSelfExpr())
|
|
90
|
-
}
|
|
91
|
-
|
|
92
78
|
/**
|
|
93
79
|
* Shared session construction: sign a credential as this function's identity
|
|
94
80
|
* carrying `grant`, bind the session to it, and wire the lazy NEXT-HOP mint.
|
|
@@ -122,7 +108,10 @@ async function bindSession(
|
|
|
122
108
|
schema: getRegistry(kernelUrl),
|
|
123
109
|
pool: getPool(kernelUrl),
|
|
124
110
|
delegation: {
|
|
125
|
-
mint: delegationMintVia(
|
|
111
|
+
mint: delegationMintVia(
|
|
112
|
+
() => session,
|
|
113
|
+
() => credential,
|
|
114
|
+
),
|
|
126
115
|
ttl: DELEGATION_TTL_SECONDS,
|
|
127
116
|
},
|
|
128
117
|
delegationPolicy: {
|
|
@@ -136,43 +125,29 @@ async function bindSession(
|
|
|
136
125
|
/**
|
|
137
126
|
* Bind a session to a PRE-SIGNED credential — no delegation mint, no composed
|
|
138
127
|
* grant; the credential IS the authority. The seam behind
|
|
139
|
-
* `
|
|
128
|
+
* `DomainAuthority.sessionFor` (a worker acting as an identity it issues). Pool +
|
|
140
129
|
* schema registry are the same per-URL caches the composed sessions use.
|
|
141
130
|
*/
|
|
142
131
|
export function bindCredentialSession(
|
|
143
132
|
kernelUrl: string,
|
|
144
133
|
credential: string,
|
|
134
|
+
opts: { delegation?: UnresolvedIdentityExpr } = {},
|
|
145
135
|
): BoundClientSessionView<FnMap> {
|
|
146
|
-
const session = new ClientSession<FnMap>({
|
|
136
|
+
const session: ClientSession<FnMap> = new ClientSession<FnMap>({
|
|
147
137
|
default: kernelUrl,
|
|
148
138
|
schema: getRegistry(kernelUrl),
|
|
149
139
|
pool: getPool(kernelUrl),
|
|
140
|
+
delegation: {
|
|
141
|
+
mint: delegationMintVia(
|
|
142
|
+
() => session,
|
|
143
|
+
() => credential,
|
|
144
|
+
),
|
|
145
|
+
ttl: DELEGATION_TTL_SECONDS,
|
|
146
|
+
},
|
|
147
|
+
delegationPolicy: {
|
|
148
|
+
...allowAllDelegations({ default: kernelUrl }),
|
|
149
|
+
delegationFor: () => opts.delegation ?? buildSelfExpr(),
|
|
150
|
+
},
|
|
150
151
|
})
|
|
151
152
|
return session.as(credential)
|
|
152
153
|
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Build the `selfKernel` accessor handed to remote-function handlers.
|
|
156
|
-
* Resolves the kernel URL from the explicit argument or `deps.KERNEL_URL`
|
|
157
|
-
* (a public request carries no credential, so the parent kernel cannot be
|
|
158
|
-
* inferred — it must be configured).
|
|
159
|
-
*/
|
|
160
|
-
export function makeSelfKernel(
|
|
161
|
-
identity: RemoteIdentityConfig,
|
|
162
|
-
deps: unknown,
|
|
163
|
-
): (kernelUrl?: string) => Promise<BoundClientSessionView<FnMap>> {
|
|
164
|
-
return async (kernelUrl?: string) => {
|
|
165
|
-
const env = deps as { INSTANCE_KERNEL_URL?: unknown; KERNEL_URL?: unknown } | null | undefined
|
|
166
|
-
// Prefer the INSTANCE kernel (the graph this domain is installed on);
|
|
167
|
-
// KERNEL_URL on managed services is the HOST kernel (the box) — wrong
|
|
168
|
-
// graph for domain writes, kept only as a last-resort fallback.
|
|
169
|
-
const url = kernelUrl ?? env?.INSTANCE_KERNEL_URL ?? env?.KERNEL_URL
|
|
170
|
-
if (typeof url !== 'string' || url.length === 0) {
|
|
171
|
-
throw new Error(
|
|
172
|
-
'selfKernel: no kernel URL — pass one explicitly or set INSTANCE_KERNEL_URL in the ' +
|
|
173
|
-
'worker env (managed deploys set it automatically).',
|
|
174
|
-
)
|
|
175
|
-
}
|
|
176
|
-
return bindSelfKernel(url, identity)
|
|
177
|
-
}
|
|
178
|
-
}
|
package/src/cli/publish.ts
CHANGED
|
@@ -176,7 +176,7 @@ export async function publishSchema(args: {
|
|
|
176
176
|
error(
|
|
177
177
|
`No schema package found (no package.json at ./schema or the current dir). A schema\n` +
|
|
178
178
|
` package declares peerDependencies (@astrale-os/kernel-core + kernel-dsl + zod) and a\n` +
|
|
179
|
-
` publishConfig that repoints main/exports to ./dist — see domains/
|
|
179
|
+
` publishConfig that repoints main/exports to ./dist — see domains/shell/schema.`,
|
|
180
180
|
)
|
|
181
181
|
return 1
|
|
182
182
|
}
|
|
@@ -153,7 +153,7 @@ export interface DefineDomainConfig<S extends Schema, TDeps, TEnv = unknown> {
|
|
|
153
153
|
* `has_parent` position: the domain's `installed_in` edge and EVERY typed
|
|
154
154
|
* address (`/:<origin>`, `/:<origin>:Class`, …) stay ROOT-mounted, so
|
|
155
155
|
* addressing is unchanged. A platform domain that must stay top-level sets its
|
|
156
|
-
* own origin path (e.g. `'/
|
|
156
|
+
* own origin path (e.g. `'/shell.astrale.ai'`).
|
|
157
157
|
*/
|
|
158
158
|
path?: string
|
|
159
159
|
/**
|
package/src/define/index.ts
CHANGED
|
@@ -23,11 +23,12 @@ import type { BoundClientSessionView } from '@astrale-os/kernel-client/session'
|
|
|
23
23
|
import type { Context } from 'hono'
|
|
24
24
|
import type { z } from 'zod'
|
|
25
25
|
|
|
26
|
-
import type {
|
|
27
|
-
import type {
|
|
28
|
-
import type { AuthForPolicy, KernelForAuth } from '../method/context'
|
|
26
|
+
import type { FunctionContextApi } from '../auth/function-context'
|
|
27
|
+
import type { DomainAuthority } from '../auth/issuer-mint'
|
|
28
|
+
import type { AuthForPolicy, CallerContext, KernelForAuth, RemoteEnv } from '../method/context'
|
|
29
|
+
import type { Step } from '../step'
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
type RemoteFunctionBaseContext<
|
|
31
32
|
TParams,
|
|
32
33
|
TDeps = unknown,
|
|
33
34
|
TKernel = BoundClientSessionView<FnMap> | null,
|
|
@@ -45,6 +46,8 @@ export type RemoteFunctionContext<
|
|
|
45
46
|
auth: AuthForPolicy<TAuth>
|
|
46
47
|
/** Typed dependency container injected at server startup. */
|
|
47
48
|
deps: TDeps
|
|
49
|
+
/** Local serving metadata. */
|
|
50
|
+
env: RemoteEnv
|
|
48
51
|
/**
|
|
49
52
|
* `BoundClientSessionView` to the parent kernel, bound to the composed
|
|
50
53
|
* credential `union(delegation, self)` — same shape as `RemoteContext.kernel`
|
|
@@ -53,32 +56,33 @@ export type RemoteFunctionContext<
|
|
|
53
56
|
* `kernel.createNode` / `kernel.mutate(patch)`, …) over the `function.get` /
|
|
54
57
|
* `function.mutate` syscalls. Nullability follows {@link KernelForAuth} of the
|
|
55
58
|
* function's `auth`: non-null for the default `'required'`, `… | null` for
|
|
56
|
-
* `'optional'`, `null` for `'public'` (use
|
|
57
|
-
*
|
|
59
|
+
* `'optional'`, `null` for `'public'` (use `ctx.fn.kernel()` there, after
|
|
60
|
+
* verifying the upstream).
|
|
58
61
|
*/
|
|
59
62
|
kernel: TKernel
|
|
60
|
-
/**
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
63
|
+
/** Inbound kernel/peer context. Present only for authenticated invocations. */
|
|
64
|
+
caller?: CallerContext
|
|
65
|
+
/** Mint seam for identities THIS DOMAIN issues. */
|
|
66
|
+
domain: DomainAuthority
|
|
67
|
+
/** Current function identity tools. */
|
|
68
|
+
fn: FunctionContextApi
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export type RemoteFunctionAuthorizeContext<
|
|
72
|
+
TParams,
|
|
73
|
+
TDeps = unknown,
|
|
74
|
+
TKernel = BoundClientSessionView<FnMap> | null,
|
|
75
|
+
TAuth extends AuthPolicy = AuthPolicy,
|
|
76
|
+
> = RemoteFunctionBaseContext<TParams, TDeps, TKernel, TAuth>
|
|
77
|
+
|
|
78
|
+
export interface RemoteFunctionContext<
|
|
79
|
+
TParams,
|
|
80
|
+
TDeps = unknown,
|
|
81
|
+
TKernel = BoundClientSessionView<FnMap> | null,
|
|
82
|
+
TAuth extends AuthPolicy = AuthPolicy,
|
|
83
|
+
> extends RemoteFunctionBaseContext<TParams, TDeps, TKernel, TAuth> {
|
|
84
|
+
/** Durable-shaped step builder. Inline today, replayable by future backends. */
|
|
85
|
+
step: Step
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
export type RemoteFunctionDef<
|
|
@@ -107,12 +111,12 @@ export type RemoteFunctionDef<
|
|
|
107
111
|
* so it drives `ctx.auth` and {@link KernelForAuth} on the
|
|
108
112
|
* `execute`/`authorize` context: omit it (or `'required'`) makes both
|
|
109
113
|
* non-null; `'optional'` widens them to `... | null`; `'public'` makes them
|
|
110
|
-
* `null` (webhooks reach the graph via `ctx.
|
|
114
|
+
* `null` (webhooks reach the graph via `ctx.fn.kernel()`).
|
|
111
115
|
*/
|
|
112
116
|
auth?: TAuth
|
|
113
117
|
/** Optional pre-execute authorization. Throw to deny. */
|
|
114
118
|
authorize?: (
|
|
115
|
-
ctx:
|
|
119
|
+
ctx: RemoteFunctionAuthorizeContext<TParams, TDeps, KernelForAuth<TAuth>, TAuth>,
|
|
116
120
|
) => void | Promise<void>
|
|
117
121
|
/** The function body. May be async. */
|
|
118
122
|
execute: (
|
package/src/define/view.ts
CHANGED
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import type { AuthPolicy, FunctionBinding } from '@astrale-os/kernel-api/routed'
|
|
24
|
-
import type { FnMap } from '@astrale-os/kernel-client'
|
|
25
|
-
import type { BoundClientSessionView } from '@astrale-os/kernel-client/session'
|
|
26
24
|
import type { EdgeEndpoint } from '@astrale-os/kernel-dsl'
|
|
27
25
|
import type { Context } from 'hono'
|
|
28
26
|
|
|
27
|
+
import type { FunctionContextApi } from '../auth/function-context'
|
|
29
28
|
import type { AuthForPolicy } from '../method/context'
|
|
29
|
+
import type { RemoteEnv } from '../method/context'
|
|
30
30
|
|
|
31
31
|
export type ViewRenderContext<TDeps = unknown, TAuth extends AuthPolicy = AuthPolicy> = {
|
|
32
32
|
/** Hono request context — read params, headers, query, etc. */
|
|
@@ -45,14 +45,10 @@ export type ViewRenderContext<TDeps = unknown, TAuth extends AuthPolicy = AuthPo
|
|
|
45
45
|
auth: AuthForPolicy<TAuth>
|
|
46
46
|
/** Typed dependency container injected at server startup. */
|
|
47
47
|
deps: TDeps
|
|
48
|
-
/**
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
* what it renders (in a seed), never root. Dials the INSTANCE kernel
|
|
53
|
-
* (`deps.INSTANCE_KERNEL_URL`, set by managed deploys) unless overridden.
|
|
54
|
-
*/
|
|
55
|
-
selfKernel: (kernelUrl?: string) => Promise<BoundClientSessionView<FnMap>>
|
|
48
|
+
/** Local serving metadata. */
|
|
49
|
+
env: RemoteEnv
|
|
50
|
+
/** View function identity tools. Use `fn.kernel()` for server-rendered graph reads. */
|
|
51
|
+
fn: FunctionContextApi
|
|
56
52
|
}
|
|
57
53
|
|
|
58
54
|
export type ViewDef<TDeps = unknown, TAuth extends AuthPolicy = AuthPolicy> = {
|
|
@@ -22,10 +22,11 @@ import type { RemoteIdentityConfig } from '../auth/identity'
|
|
|
22
22
|
import type { AnyRemoteHandler } from '../method/single'
|
|
23
23
|
import type { MethodIndex } from './resolve'
|
|
24
24
|
|
|
25
|
-
import {
|
|
25
|
+
import { makeFunctionContext } from '../auth/function-context'
|
|
26
|
+
import { makeDomainAuthority } from '../auth/issuer-mint'
|
|
26
27
|
import { resolveInboundAuth } from '../auth/resolve'
|
|
28
|
+
import { createInlineStep } from '../step'
|
|
27
29
|
import { runAuthorize } from './authorize'
|
|
28
|
-
import { makeCallRemote } from './call-remote'
|
|
29
30
|
import { MethodNotFoundError, SdkResultValidationError, SdkValidationError } from './errors'
|
|
30
31
|
import { executeHandler } from './execute'
|
|
31
32
|
import { buildIdentityMap } from './identity'
|
|
@@ -51,7 +52,7 @@ export type SdkDispatcherConfig<TDeps> = {
|
|
|
51
52
|
* install (the URL it fetched the domain at).
|
|
52
53
|
*/
|
|
53
54
|
issuer: string
|
|
54
|
-
/** The worker's serving URL (`config.url`) — exposed to handlers as `ctx.url`. */
|
|
55
|
+
/** The worker's serving URL (`config.url`) — exposed to handlers as `ctx.env.url`. */
|
|
55
56
|
url: string
|
|
56
57
|
/**
|
|
57
58
|
* The domain schema. When present, non-static handlers receive the rich,
|
|
@@ -189,7 +190,6 @@ export class SdkDispatcher<TDeps = unknown> implements KernelAPI {
|
|
|
189
190
|
authorize?: (ctx: unknown) => void | Promise<void>
|
|
190
191
|
}
|
|
191
192
|
const handlerParams = validation.data
|
|
192
|
-
const callRemote = makeCallRemote(kernel)
|
|
193
193
|
// Enrich the parsed self with the lazy `node()` accessor, bound to this
|
|
194
194
|
// request's kernel (null when the auth policy yields none — `node()` then
|
|
195
195
|
// rejects). Done here, not in `resolveSelf`, so the parse stays kernel-free.
|
|
@@ -200,20 +200,46 @@ export class SdkDispatcher<TDeps = unknown> implements KernelAPI {
|
|
|
200
200
|
? withBoundNode(parsedSelf, kernel, this.binder, bound.owner)
|
|
201
201
|
: withNode(parsedSelf, kernel)
|
|
202
202
|
: undefined
|
|
203
|
+
const inboundIss = auth?.credential?.verified?.iss as string | undefined
|
|
204
|
+
const kernelUrl = kernel?.default ?? inboundIss
|
|
205
|
+
const caller =
|
|
206
|
+
auth && inboundIss
|
|
207
|
+
? {
|
|
208
|
+
iss: inboundIss,
|
|
209
|
+
url: kernelUrl ?? inboundIss,
|
|
210
|
+
}
|
|
211
|
+
: undefined
|
|
212
|
+
|
|
203
213
|
const ctx = {
|
|
204
214
|
params: handlerParams,
|
|
205
215
|
auth,
|
|
206
216
|
self,
|
|
207
217
|
deps: this.deps,
|
|
208
|
-
url: this.url,
|
|
218
|
+
env: { url: this.url },
|
|
209
219
|
kernel,
|
|
210
|
-
|
|
211
|
-
|
|
220
|
+
...(caller !== undefined ? { caller } : {}),
|
|
221
|
+
domain: makeDomainAuthority(fnIdentity),
|
|
222
|
+
fn: makeFunctionContext(fnIdentity, this.deps, {
|
|
223
|
+
ref: bound.ref,
|
|
224
|
+
...(kernelUrl !== undefined ? { defaultKernelUrl: kernelUrl } : {}),
|
|
225
|
+
}),
|
|
212
226
|
}
|
|
213
227
|
|
|
214
228
|
if (handler.authorize) await runAuthorize(handler.authorize, ctx)
|
|
215
229
|
|
|
216
|
-
const result = await executeHandler({
|
|
230
|
+
const result = await executeHandler({
|
|
231
|
+
handler,
|
|
232
|
+
ref: bound.ref,
|
|
233
|
+
...ctx,
|
|
234
|
+
step: createInlineStep({
|
|
235
|
+
scope: {
|
|
236
|
+
kind: 'method',
|
|
237
|
+
ref: bound.ref,
|
|
238
|
+
owner: bound.owner,
|
|
239
|
+
method: bound.method,
|
|
240
|
+
},
|
|
241
|
+
}),
|
|
242
|
+
})
|
|
217
243
|
return validateOutput(bound, result)
|
|
218
244
|
}
|
|
219
245
|
|
package/src/dispatch/execute.ts
CHANGED
|
@@ -11,8 +11,10 @@ import type { FnMap } from '@astrale-os/kernel-client'
|
|
|
11
11
|
import type { BoundClientSessionView } from '@astrale-os/kernel-client/session'
|
|
12
12
|
import type { AuthContext } from '@astrale-os/kernel-core'
|
|
13
13
|
|
|
14
|
-
import type {
|
|
15
|
-
import type {
|
|
14
|
+
import type { FunctionContextApi } from '../auth/function-context'
|
|
15
|
+
import type { DomainAuthority } from '../auth/issuer-mint'
|
|
16
|
+
import type { CallerContext, RemoteEnv } from '../method/context'
|
|
17
|
+
import type { Step } from '../step'
|
|
16
18
|
import type { SelfResult, TypedSelf } from './self'
|
|
17
19
|
|
|
18
20
|
// oxlint-disable-next-line no-explicit-any
|
|
@@ -29,11 +31,13 @@ export type ExecuteParams = {
|
|
|
29
31
|
/** Untyped fallback ({@link withNode}) or the rich typed self ({@link withBoundNode}). */
|
|
30
32
|
self: SelfResult | TypedSelf<unknown> | undefined
|
|
31
33
|
deps: unknown
|
|
32
|
-
|
|
34
|
+
env: RemoteEnv
|
|
33
35
|
kernel: BoundClientSessionView<FnMap> | null
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
caller?: CallerContext
|
|
37
|
+
/** Mint seam for identities this domain issues. */
|
|
38
|
+
domain: DomainAuthority
|
|
39
|
+
fn: FunctionContextApi
|
|
40
|
+
step: Step
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
export async function executeHandler(ctx: ExecuteParams): Promise<unknown> {
|
|
@@ -48,9 +52,11 @@ export async function executeHandler(ctx: ExecuteParams): Promise<unknown> {
|
|
|
48
52
|
auth: ctx.auth,
|
|
49
53
|
self: ctx.self,
|
|
50
54
|
deps: ctx.deps,
|
|
51
|
-
|
|
55
|
+
env: ctx.env,
|
|
52
56
|
kernel: ctx.kernel,
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
...(ctx.caller !== undefined ? { caller: ctx.caller } : {}),
|
|
58
|
+
domain: ctx.domain,
|
|
59
|
+
fn: ctx.fn,
|
|
60
|
+
step: ctx.step,
|
|
55
61
|
})
|
|
56
62
|
}
|
package/src/dispatch/index.ts
CHANGED
|
@@ -8,7 +8,6 @@ export {
|
|
|
8
8
|
} from './validate'
|
|
9
9
|
export { resolveSelf, withBoundNode, type SelfResult, type TypedSelf } from './self'
|
|
10
10
|
export { executeHandler, type ExecuteParams } from './execute'
|
|
11
|
-
export { makeCallRemote, type CallRemoteFn, type KernelCaller } from './call-remote'
|
|
12
11
|
export {
|
|
13
12
|
AuthorizationDeniedError,
|
|
14
13
|
MethodNotFoundError,
|
package/src/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ export type {
|
|
|
6
6
|
GraphApi,
|
|
7
7
|
Kernel,
|
|
8
8
|
KernelForAuth,
|
|
9
|
+
RemoteAuthorizeContext,
|
|
9
10
|
RemoteContext,
|
|
10
11
|
RemoteHandler,
|
|
11
12
|
MethodImpl,
|
|
@@ -66,7 +67,16 @@ export type {
|
|
|
66
67
|
// entry's `render` / `execute` (+ auth hooks) is mounted as a worker route by
|
|
67
68
|
// `createRemoteServer`.
|
|
68
69
|
export { defineView, defineRemoteFunction } from './define'
|
|
69
|
-
export type {
|
|
70
|
+
export type {
|
|
71
|
+
ViewDef,
|
|
72
|
+
ViewRenderContext,
|
|
73
|
+
RemoteFunctionAuthorizeContext,
|
|
74
|
+
RemoteFunctionDef,
|
|
75
|
+
RemoteFunctionContext,
|
|
76
|
+
} from './define'
|
|
77
|
+
|
|
78
|
+
// ─── Durable-shaped steps ────────────────────────────────────────────────
|
|
79
|
+
export type { Step } from './step'
|
|
70
80
|
|
|
71
81
|
// ─── Server ──────────────────────────────────────────────────────────────
|
|
72
82
|
// `createRemoteServer` dynamically imports `@hono/node-server` via `./server/start`.
|
|
@@ -97,12 +107,17 @@ export type {
|
|
|
97
107
|
|
|
98
108
|
// ─── Auth ────────────────────────────────────────────────────────────────
|
|
99
109
|
export type { RemoteIdentityConfig, AuthenticateResult } from './auth'
|
|
100
|
-
export type {
|
|
110
|
+
export type {
|
|
111
|
+
DomainAuthority,
|
|
112
|
+
FunctionContextApi,
|
|
113
|
+
FunctionCredentialOptions,
|
|
114
|
+
FunctionKernelOptions,
|
|
115
|
+
MintIssuedParams,
|
|
116
|
+
} from './auth'
|
|
101
117
|
export {
|
|
102
118
|
authenticateRequest,
|
|
103
|
-
bindSelfKernel,
|
|
104
119
|
buildComposedGrant,
|
|
105
|
-
|
|
120
|
+
makeFunctionContext,
|
|
106
121
|
signCredential,
|
|
107
122
|
} from './auth'
|
|
108
123
|
export { AuthMissingError, AuthInvalidError } from './auth'
|
|
@@ -125,4 +140,4 @@ export {
|
|
|
125
140
|
SdkValidationError,
|
|
126
141
|
SdkResultValidationError,
|
|
127
142
|
} from './dispatch'
|
|
128
|
-
export type { SelfResult, TypedSelf
|
|
143
|
+
export type { SelfResult, TypedSelf } from './dispatch'
|
package/src/method/context.ts
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Assembled by the dispatch pipeline before calling `execute`. Carries the
|
|
5
5
|
* validated params, the resolved auth context, the bound node instance (for
|
|
6
6
|
* non-static methods), the typed dependency container, and a
|
|
7
|
-
* `BoundClientSessionView` to call back into the parent kernel
|
|
7
|
+
* `BoundClientSessionView` to call back into the parent kernel, plus explicit
|
|
8
|
+
* `domain`, `caller`, and `fn` namespaces for identity-sensitive work.
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
import type { AuthPolicy } from '@astrale-os/kernel-api/routed'
|
|
@@ -12,8 +13,9 @@ import type { FnMap } from '@astrale-os/kernel-client'
|
|
|
12
13
|
import type { BoundClientSessionView } from '@astrale-os/kernel-client/session'
|
|
13
14
|
import type { AuthContext } from '@astrale-os/kernel-core'
|
|
14
15
|
|
|
15
|
-
import type {
|
|
16
|
-
import type {
|
|
16
|
+
import type { FunctionContextApi } from '../auth/function-context'
|
|
17
|
+
import type { DomainAuthority } from '../auth/issuer-mint'
|
|
18
|
+
import type { Step } from '../step'
|
|
17
19
|
|
|
18
20
|
export type { GraphApi } from '@astrale-os/kernel-client/graph'
|
|
19
21
|
|
|
@@ -33,8 +35,8 @@ export type Kernel = BoundClientSessionView<FnMap>
|
|
|
33
35
|
* - `'required'` (the default) — the dispatcher rejects a credentialless call
|
|
34
36
|
* before `execute`, so the kernel is ALWAYS present → non-null.
|
|
35
37
|
* - `'optional'` — a kernel only when a credential was supplied → `… | null`.
|
|
36
|
-
* - `'public'` — never any inbound credential → `null`.
|
|
37
|
-
* must touch the graph use `
|
|
38
|
+
* - `'public'` — never any inbound credential → `null`. Public handlers that
|
|
39
|
+
* must touch the graph use `ctx.fn.kernel()` after verifying their upstream.
|
|
38
40
|
*
|
|
39
41
|
* Distributes over a `AuthPolicy` union (e.g. when `auth` is typed but not a
|
|
40
42
|
* literal) to the widened `Kernel | null` — the safe superset, matching the
|
|
@@ -57,7 +59,19 @@ export type AuthForPolicy<TAuth extends AuthPolicy> = TAuth extends 'public'
|
|
|
57
59
|
? AuthContext | null
|
|
58
60
|
: AuthContext
|
|
59
61
|
|
|
60
|
-
export type
|
|
62
|
+
export type RemoteEnv = {
|
|
63
|
+
/** This worker's canonical serving URL. */
|
|
64
|
+
url: string
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export type CallerContext = {
|
|
68
|
+
/** Issuer of the inbound kernel/peer credential. */
|
|
69
|
+
iss: string
|
|
70
|
+
/** Kernel URL associated with this invocation. */
|
|
71
|
+
url: string
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
type RemoteBaseContext<
|
|
61
75
|
TParams,
|
|
62
76
|
TSelf,
|
|
63
77
|
TDeps,
|
|
@@ -76,8 +90,8 @@ export type RemoteContext<
|
|
|
76
90
|
self: TSelf
|
|
77
91
|
/** Typed dependency container injected at server startup. */
|
|
78
92
|
deps: TDeps
|
|
79
|
-
/**
|
|
80
|
-
|
|
93
|
+
/** Local serving metadata. */
|
|
94
|
+
env: RemoteEnv
|
|
81
95
|
/**
|
|
82
96
|
* `BoundClientSessionView` to the parent kernel, bound to the composed
|
|
83
97
|
* credential `union(delegation, self)`. Its nullability is `{@link
|
|
@@ -88,26 +102,34 @@ export type RemoteContext<
|
|
|
88
102
|
* plus `kernel.createNode` / `kernel.updateNode` /
|
|
89
103
|
* `kernel.deleteNode` / `kernel.createEdge` / `kernel.updateEdge` /
|
|
90
104
|
* `kernel.deleteEdge` / `kernel.mutate(patch)`) over the `function.get` /
|
|
91
|
-
* `function.mutate` syscalls.
|
|
92
|
-
*
|
|
93
|
-
*
|
|
105
|
+
* `function.mutate` syscalls. Remote-bound calls are made with
|
|
106
|
+
* `kernel.call(...)`; the client follows redirects and remints the next-hop
|
|
107
|
+
* delegation under the current bound authority.
|
|
94
108
|
*/
|
|
95
109
|
kernel: TKernel
|
|
96
|
-
/**
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
/** Inbound kernel/peer context. Present only for authenticated invocations. */
|
|
111
|
+
caller?: CallerContext
|
|
112
|
+
/** Mint seam for identities THIS DOMAIN issues (`iss` = this worker). */
|
|
113
|
+
domain: DomainAuthority
|
|
114
|
+
/** Current function identity tools: grant-bearing credentials and self-bound kernels. */
|
|
115
|
+
fn: FunctionContextApi
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export type RemoteAuthorizeContext<
|
|
119
|
+
TParams,
|
|
120
|
+
TSelf,
|
|
121
|
+
TDeps,
|
|
122
|
+
TKernel = Kernel | null,
|
|
123
|
+
TAuth extends AuthPolicy = AuthPolicy,
|
|
124
|
+
> = RemoteBaseContext<TParams, TSelf, TDeps, TKernel, TAuth>
|
|
125
|
+
|
|
126
|
+
export interface RemoteContext<
|
|
127
|
+
TParams,
|
|
128
|
+
TSelf,
|
|
129
|
+
TDeps,
|
|
130
|
+
TKernel = Kernel | null,
|
|
131
|
+
TAuth extends AuthPolicy = AuthPolicy,
|
|
132
|
+
> extends RemoteBaseContext<TParams, TSelf, TDeps, TKernel, TAuth> {
|
|
133
|
+
/** Durable-shaped step builder. Inline today, replayable by future backends. */
|
|
134
|
+
step: Step
|
|
113
135
|
}
|
package/src/method/index.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type {
|
|
2
|
+
AuthForPolicy,
|
|
3
|
+
GraphApi,
|
|
4
|
+
Kernel,
|
|
5
|
+
KernelForAuth,
|
|
6
|
+
RemoteAuthorizeContext,
|
|
7
|
+
RemoteContext,
|
|
8
|
+
} from './context'
|
|
2
9
|
export type {
|
|
3
10
|
RemoteHandler,
|
|
4
11
|
AnyRemoteHandler,
|
package/src/method/single.ts
CHANGED
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
import type { Schema } from '@astrale-os/kernel-dsl'
|
|
11
11
|
|
|
12
12
|
import type { TypedSelf } from '../dispatch/self'
|
|
13
|
-
import type { KernelForAuth, RemoteContext } from './context'
|
|
13
|
+
import type { KernelForAuth, RemoteAuthorizeContext, RemoteContext } from './context'
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Remote method handler. `execute` is optional only for binding stubs; any
|
|
@@ -47,7 +47,7 @@ export type RemoteHandler<TParams, TResult, TSelf, TDeps, TAuth extends AuthPoli
|
|
|
47
47
|
* has_perm checks remain authoritative; this is additive gating.
|
|
48
48
|
*/
|
|
49
49
|
authorize?: (
|
|
50
|
-
ctx:
|
|
50
|
+
ctx: RemoteAuthorizeContext<TParams, TSelf, TDeps, KernelForAuth<TAuth>, TAuth>,
|
|
51
51
|
) => void | Promise<void>
|
|
52
52
|
}
|
|
53
53
|
|