@astrale-os/sdk 0.1.1 → 0.1.3

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.
Files changed (198) hide show
  1. package/dist/auth/authenticate.d.ts +24 -0
  2. package/dist/auth/authenticate.d.ts.map +1 -0
  3. package/dist/auth/authenticate.js +29 -0
  4. package/dist/auth/authenticate.js.map +1 -0
  5. package/dist/auth/check.d.ts +39 -0
  6. package/dist/auth/check.d.ts.map +1 -0
  7. package/dist/auth/check.js +54 -0
  8. package/dist/auth/check.js.map +1 -0
  9. package/dist/auth/compose.d.ts +41 -0
  10. package/dist/auth/compose.d.ts.map +1 -0
  11. package/dist/auth/compose.js +45 -0
  12. package/dist/auth/compose.js.map +1 -0
  13. package/dist/auth/errors.d.ts +16 -0
  14. package/dist/auth/errors.d.ts.map +1 -0
  15. package/dist/auth/errors.js +26 -0
  16. package/dist/auth/errors.js.map +1 -0
  17. package/dist/auth/identity.d.ts +16 -0
  18. package/dist/auth/identity.d.ts.map +1 -0
  19. package/dist/auth/identity.js +2 -0
  20. package/dist/auth/identity.js.map +1 -0
  21. package/dist/auth/index.d.ts +12 -0
  22. package/dist/auth/index.d.ts.map +1 -0
  23. package/dist/auth/index.js +9 -0
  24. package/dist/auth/index.js.map +1 -0
  25. package/dist/auth/kernel-client.d.ts +43 -0
  26. package/dist/auth/kernel-client.d.ts.map +1 -0
  27. package/dist/auth/kernel-client.js +146 -0
  28. package/dist/auth/kernel-client.js.map +1 -0
  29. package/dist/auth/resolve.d.ts +19 -0
  30. package/dist/auth/resolve.d.ts.map +1 -0
  31. package/dist/auth/resolve.js +43 -0
  32. package/dist/auth/resolve.js.map +1 -0
  33. package/dist/auth/sign.d.ts +15 -0
  34. package/dist/auth/sign.d.ts.map +1 -0
  35. package/dist/auth/sign.js +24 -0
  36. package/dist/auth/sign.js.map +1 -0
  37. package/dist/auth/verify.d.ts +26 -0
  38. package/dist/auth/verify.d.ts.map +1 -0
  39. package/dist/auth/verify.js +96 -0
  40. package/dist/auth/verify.js.map +1 -0
  41. package/dist/define/index.d.ts +5 -0
  42. package/dist/define/index.d.ts.map +1 -0
  43. package/dist/define/index.js +3 -0
  44. package/dist/define/index.js.map +1 -0
  45. package/dist/define/remote-function.d.ts +96 -0
  46. package/dist/define/remote-function.d.ts.map +1 -0
  47. package/dist/define/remote-function.js +25 -0
  48. package/dist/define/remote-function.js.map +1 -0
  49. package/dist/define/view.d.ts +86 -0
  50. package/dist/define/view.d.ts.map +1 -0
  51. package/dist/define/view.js +28 -0
  52. package/dist/define/view.js.map +1 -0
  53. package/dist/deploy/check.d.ts +30 -0
  54. package/dist/deploy/check.d.ts.map +1 -0
  55. package/dist/deploy/check.js +82 -0
  56. package/dist/deploy/check.js.map +1 -0
  57. package/dist/deploy/hash-spec.d.ts +9 -0
  58. package/dist/deploy/hash-spec.d.ts.map +1 -0
  59. package/dist/deploy/hash-spec.js +29 -0
  60. package/dist/deploy/hash-spec.js.map +1 -0
  61. package/dist/deploy/index.d.ts +4 -0
  62. package/dist/deploy/index.d.ts.map +1 -0
  63. package/dist/deploy/index.js +4 -0
  64. package/dist/deploy/index.js.map +1 -0
  65. package/dist/deploy/meta.d.ts +18 -0
  66. package/dist/deploy/meta.d.ts.map +1 -0
  67. package/dist/deploy/meta.js +22 -0
  68. package/dist/deploy/meta.js.map +1 -0
  69. package/dist/dispatch/authorize.d.ts +14 -0
  70. package/dist/dispatch/authorize.d.ts.map +1 -0
  71. package/dist/dispatch/authorize.js +24 -0
  72. package/dist/dispatch/authorize.js.map +1 -0
  73. package/dist/dispatch/call-remote.d.ts +35 -0
  74. package/dist/dispatch/call-remote.d.ts.map +1 -0
  75. package/dist/dispatch/call-remote.js +37 -0
  76. package/dist/dispatch/call-remote.js.map +1 -0
  77. package/dist/dispatch/dispatcher.d.ts +60 -0
  78. package/dist/dispatch/dispatcher.d.ts.map +1 -0
  79. package/dist/dispatch/dispatcher.js +177 -0
  80. package/dist/dispatch/dispatcher.js.map +1 -0
  81. package/dist/dispatch/errors.d.ts +47 -0
  82. package/dist/dispatch/errors.d.ts.map +1 -0
  83. package/dist/dispatch/errors.js +76 -0
  84. package/dist/dispatch/errors.js.map +1 -0
  85. package/dist/dispatch/execute.d.ts +33 -0
  86. package/dist/dispatch/execute.d.ts.map +1 -0
  87. package/dist/dispatch/execute.js +24 -0
  88. package/dist/dispatch/execute.js.map +1 -0
  89. package/dist/dispatch/identity.d.ts +73 -0
  90. package/dist/dispatch/identity.d.ts.map +1 -0
  91. package/dist/dispatch/identity.js +106 -0
  92. package/dist/dispatch/identity.js.map +1 -0
  93. package/dist/dispatch/index.d.ts +8 -0
  94. package/dist/dispatch/index.d.ts.map +1 -0
  95. package/dist/dispatch/index.js +8 -0
  96. package/dist/dispatch/index.js.map +1 -0
  97. package/dist/dispatch/resolve.d.ts +27 -0
  98. package/dist/dispatch/resolve.d.ts.map +1 -0
  99. package/dist/dispatch/resolve.js +65 -0
  100. package/dist/dispatch/resolve.js.map +1 -0
  101. package/dist/dispatch/self.d.ts +27 -0
  102. package/dist/dispatch/self.d.ts.map +1 -0
  103. package/dist/dispatch/self.js +25 -0
  104. package/dist/dispatch/self.js.map +1 -0
  105. package/dist/dispatch/validate.d.ts +35 -0
  106. package/dist/dispatch/validate.d.ts.map +1 -0
  107. package/dist/dispatch/validate.js +27 -0
  108. package/dist/dispatch/validate.js.map +1 -0
  109. package/dist/domain/build-spec.d.ts +37 -0
  110. package/dist/domain/build-spec.d.ts.map +1 -0
  111. package/dist/domain/build-spec.js +95 -0
  112. package/dist/domain/build-spec.js.map +1 -0
  113. package/dist/domain/contract.d.ts +17 -0
  114. package/dist/domain/contract.d.ts.map +1 -0
  115. package/dist/domain/contract.js +26 -0
  116. package/dist/domain/contract.js.map +1 -0
  117. package/dist/domain/define.d.ts +82 -0
  118. package/dist/domain/define.d.ts.map +1 -0
  119. package/dist/domain/define.js +99 -0
  120. package/dist/domain/define.js.map +1 -0
  121. package/dist/domain/extend-core.d.ts +49 -0
  122. package/dist/domain/extend-core.d.ts.map +1 -0
  123. package/dist/domain/extend-core.js +182 -0
  124. package/dist/domain/extend-core.js.map +1 -0
  125. package/dist/domain/index.d.ts +5 -0
  126. package/dist/domain/index.d.ts.map +1 -0
  127. package/dist/domain/index.js +4 -0
  128. package/dist/domain/index.js.map +1 -0
  129. package/dist/index.d.ts +19 -0
  130. package/dist/index.d.ts.map +1 -0
  131. package/dist/index.js +32 -0
  132. package/dist/index.js.map +1 -0
  133. package/dist/method/class.d.ts +70 -0
  134. package/dist/method/class.d.ts.map +1 -0
  135. package/dist/method/class.js +26 -0
  136. package/dist/method/class.js.map +1 -0
  137. package/dist/method/context.d.ts +43 -0
  138. package/dist/method/context.d.ts.map +1 -0
  139. package/dist/method/context.js +10 -0
  140. package/dist/method/context.js.map +1 -0
  141. package/dist/method/index.d.ts +6 -0
  142. package/dist/method/index.d.ts.map +1 -0
  143. package/dist/method/index.js +3 -0
  144. package/dist/method/index.js.map +1 -0
  145. package/dist/method/single.d.ts +88 -0
  146. package/dist/method/single.d.ts.map +1 -0
  147. package/dist/method/single.js +18 -0
  148. package/dist/method/single.js.map +1 -0
  149. package/dist/server/auxiliary-routes.d.ts +44 -0
  150. package/dist/server/auxiliary-routes.d.ts.map +1 -0
  151. package/dist/server/auxiliary-routes.js +239 -0
  152. package/dist/server/auxiliary-routes.js.map +1 -0
  153. package/dist/server/config.d.ts +83 -0
  154. package/dist/server/config.d.ts.map +1 -0
  155. package/dist/server/config.js +8 -0
  156. package/dist/server/config.js.map +1 -0
  157. package/dist/server/create.d.ts +21 -0
  158. package/dist/server/create.d.ts.map +1 -0
  159. package/dist/server/create.js +210 -0
  160. package/dist/server/create.js.map +1 -0
  161. package/dist/server/handle.d.ts +35 -0
  162. package/dist/server/handle.d.ts.map +1 -0
  163. package/dist/server/handle.js +9 -0
  164. package/dist/server/handle.js.map +1 -0
  165. package/dist/server/index.d.ts +11 -0
  166. package/dist/server/index.d.ts.map +1 -0
  167. package/dist/server/index.js +8 -0
  168. package/dist/server/index.js.map +1 -0
  169. package/dist/server/jwks.d.ts +11 -0
  170. package/dist/server/jwks.d.ts.map +1 -0
  171. package/dist/server/jwks.js +15 -0
  172. package/dist/server/jwks.js.map +1 -0
  173. package/dist/server/require-env.d.ts +15 -0
  174. package/dist/server/require-env.d.ts.map +1 -0
  175. package/dist/server/require-env.js +21 -0
  176. package/dist/server/require-env.js.map +1 -0
  177. package/dist/server/serving-url.d.ts +14 -0
  178. package/dist/server/serving-url.d.ts.map +1 -0
  179. package/dist/server/serving-url.js +28 -0
  180. package/dist/server/serving-url.js.map +1 -0
  181. package/dist/server/start.d.ts +11 -0
  182. package/dist/server/start.d.ts.map +1 -0
  183. package/dist/server/start.js +34 -0
  184. package/dist/server/start.js.map +1 -0
  185. package/dist/server/worker-entry.d.ts +60 -0
  186. package/dist/server/worker-entry.d.ts.map +1 -0
  187. package/dist/server/worker-entry.js +79 -0
  188. package/dist/server/worker-entry.js.map +1 -0
  189. package/dist/server/worker-meta.d.ts +6 -0
  190. package/dist/server/worker-meta.d.ts.map +1 -0
  191. package/dist/server/worker-meta.js +10 -0
  192. package/dist/server/worker-meta.js.map +1 -0
  193. package/package.json +5 -5
  194. package/src/auth/compose.ts +27 -2
  195. package/src/auth/kernel-client.ts +103 -11
  196. package/src/define/remote-function.ts +10 -0
  197. package/src/server/auxiliary-routes.ts +3 -1
  198. package/src/server/start.ts +5 -1
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Shared inbound-credential resolution.
3
+ *
4
+ * Consumed by both `SdkDispatcher` (kernel envelope) and `mountAuxiliaryRoutes`
5
+ * (View / RemoteFunction routes). Centralises the auth-policy three-way
6
+ * (`'required'` / `'optional'` / `'public'`) and the wrap of underlying
7
+ * verification errors into canonical `AuthMissingError` / `AuthInvalidError`.
8
+ */
9
+ import { isKernelErrorClassifiable } from '@astrale-os/kernel-api';
10
+ import { authenticateRequest } from './authenticate';
11
+ import { AuthInvalidError, AuthMissingError } from './errors';
12
+ export async function resolveInboundAuth(credential, policy, identity) {
13
+ const effective = policy ?? 'required';
14
+ if (effective === 'public')
15
+ return { auth: null, kernel: null };
16
+ if (effective === 'optional' && !credential)
17
+ return { auth: null, kernel: null };
18
+ if (effective === 'required' && !credential)
19
+ throw new AuthMissingError();
20
+ try {
21
+ const result = await authenticateRequest(credential, identity);
22
+ return { auth: buildAuthContext(result.authenticated), kernel: result.kernel };
23
+ }
24
+ catch (err) {
25
+ // kernel-core auth errors (UntrustedIssuerError, TrustPolicyDeniedError, …)
26
+ // already self-classify with a discriminating `data.type`. Rethrow them
27
+ // unchanged so that classification survives to the wire; only wrap
28
+ // genuinely unclassified errors into the generic AuthInvalidError.
29
+ if (isKernelErrorClassifiable(err))
30
+ throw err;
31
+ throw new AuthInvalidError(err instanceof Error ? err.message : 'Authentication failed', err);
32
+ }
33
+ }
34
+ export function buildAuthContext(authenticated) {
35
+ return {
36
+ credential: authenticated.credential,
37
+ principal: authenticated.credential.verified.sub,
38
+ grant: authenticated.grant,
39
+ attestation: authenticated.attestation,
40
+ delegation: authenticated.delegation,
41
+ };
42
+ }
43
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/auth/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAA;AAKlE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAO7D,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAA2B,EAC3B,MAA8B,EAC9B,QAA8B;IAE9B,MAAM,SAAS,GAAG,MAAM,IAAI,UAAU,CAAA;IAEtC,IAAI,SAAS,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;IAC/D,IAAI,SAAS,KAAK,UAAU,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;IAChF,IAAI,SAAS,KAAK,UAAU,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,gBAAgB,EAAE,CAAA;IAEzE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;QAC9D,OAAO,EAAE,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAA;IAChF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,4EAA4E;QAC5E,wEAAwE;QACxE,mEAAmE;QACnE,mEAAmE;QACnE,IAAI,yBAAyB,CAAC,GAAG,CAAC;YAAE,MAAM,GAAG,CAAA;QAC7C,MAAM,IAAI,gBAAgB,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAA;IAC/F,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,aAA4B;IAC3D,OAAO;QACL,UAAU,EAAE,aAAa,CAAC,UAAU;QACpC,SAAS,EAAE,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC,GAA4B;QACzE,KAAK,EAAE,aAAa,CAAC,KAAM;QAC3B,WAAW,EAAE,aAAa,CAAC,WAAW;QACtC,UAAU,EAAE,aAAa,CAAC,UAAU;KACrC,CAAA;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * JWT signing utilities for outbound composed credentials.
3
+ */
4
+ /**
5
+ * Sign a credential JWT with the given claims and identity config.
6
+ */
7
+ export declare function signCredential(claims: Record<string, unknown>, config: {
8
+ issuer: string;
9
+ subject: string;
10
+ audience: string;
11
+ privateKey: JsonWebKey;
12
+ /** JWT lifetime as a jose-compatible string (e.g. '60s', '5m', '1h'). Default: '60s'. */
13
+ ttl?: string;
14
+ }): Promise<string>;
15
+ //# sourceMappingURL=sign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../../src/auth/sign.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;GAEG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE;IACN,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,UAAU,CAAA;IACtB,yFAAyF;IACzF,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,GACA,OAAO,CAAC,MAAM,CAAC,CAejB"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * JWT signing utilities for outbound composed credentials.
3
+ */
4
+ import { deriveAllowedAlgorithms } from '@astrale-os/kernel-core';
5
+ import { SignJWT, importJWK } from 'jose';
6
+ /**
7
+ * Sign a credential JWT with the given claims and identity config.
8
+ */
9
+ export async function signCredential(claims, config) {
10
+ const alg = deriveAllowedAlgorithms(config.privateKey)[0];
11
+ if (!alg) {
12
+ throw new Error(`Cannot derive algorithm from JWK: kty=${config.privateKey.kty}`);
13
+ }
14
+ const key = await importJWK(config.privateKey, alg);
15
+ return new SignJWT(claims)
16
+ .setProtectedHeader({ alg })
17
+ .setIssuer(config.issuer)
18
+ .setSubject(config.subject)
19
+ .setAudience(config.audience)
20
+ .setIssuedAt()
21
+ .setExpirationTime(config.ttl ?? '60s')
22
+ .sign(key);
23
+ }
24
+ //# sourceMappingURL=sign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign.js","sourceRoot":"","sources":["../../src/auth/sign.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAEzC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAA+B,EAC/B,MAOC;IAED,MAAM,GAAG,GAAG,uBAAuB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;IACzD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,yCAAyC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,CAAA;IACnF,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;IAEnD,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB,kBAAkB,CAAC,EAAE,GAAG,EAAE,CAAC;SAC3B,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC;SACxB,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC;SAC1B,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC;SAC5B,WAAW,EAAE;SACb,iBAAiB,CAAC,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC;SACtC,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Inbound credential verification.
3
+ *
4
+ * Uses kernel-core's credential verification infrastructure
5
+ * (CredentialMethodResolver, MethodRegistry) instead of manual JWT handling.
6
+ * Not tied to JWT — supports any credential method kernel-core provides.
7
+ */
8
+ import type { Attestation, CredentialInput, Delegation, VerifiedCredential } from '@astrale-os/kernel-core';
9
+ import type { RemoteIdentityConfig } from './identity';
10
+ export type VerifiedInbound = {
11
+ /** The full verified credential (iss, sub, aud, claims) */
12
+ verified: VerifiedCredential;
13
+ /** Issuer URL (from credential's iss claim) */
14
+ issuer: string;
15
+ /** Attestation — proves caller can invoke this function */
16
+ attestation: Attestation;
17
+ /** Delegation — scoped caller permissions as kernel-signed credential */
18
+ delegation: Delegation;
19
+ };
20
+ /**
21
+ * Verify an inbound delegation credential using kernel-core's verification.
22
+ *
23
+ * @throws AuthenticationError subclasses from kernel-core on verification failure
24
+ */
25
+ export declare function verifyInboundCredential(credential: CredentialInput, config: RemoteIdentityConfig): Promise<VerifiedInbound>;
26
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/auth/verify.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,UAAU,EAEV,kBAAkB,EACnB,MAAM,yBAAyB,CAAA;AAUhC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAKtD,MAAM,MAAM,eAAe,GAAG;IAC5B,2DAA2D;IAC3D,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAA;IACd,2DAA2D;IAC3D,WAAW,EAAE,WAAW,CAAA;IACxB,yEAAyE;IACzE,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA;AA4DD;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,eAAe,CAAC,CA+B1B"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Inbound credential verification.
3
+ *
4
+ * Uses kernel-core's credential verification infrastructure
5
+ * (CredentialMethodResolver, MethodRegistry) instead of manual JWT handling.
6
+ * Not tied to JWT — supports any credential method kernel-core provides.
7
+ */
8
+ import { CredentialMethodResolver, MethodRegistry, verifyAudience, verifyCredential, } from '@astrale-os/kernel-core';
9
+ import { createLocalJWKSet, createRemoteJWKSet } from 'jose';
10
+ import { derivePublicJwk } from '../server/jwks';
11
+ import { canonicalizeServingUrl } from '../server/serving-url';
12
+ const methodResolver = new CredentialMethodResolver(new MethodRegistry());
13
+ /**
14
+ * Build the key resolver for one verifying server. Captures `config` so it can
15
+ * short-circuit the server's OWN issuer (`config.issuer`): a self-issued
16
+ * credential is verified against the in-memory public key, never fetched — a
17
+ * Worker can't fetch its own hostname, and it already holds the key. Every other
18
+ * issuer is resolved live via JWKS (`createRemoteJWKSet`).
19
+ */
20
+ function makeResolveKeys(config) {
21
+ // The worker's own canonical iss. STRICT: `config.issuer` is the serving URL
22
+ // by contract (both producers — buildIdentityMap / buildAuxIdentityMap — feed
23
+ // it `canonicalizeServingUrl(config.url)`), so a value that doesn't parse is
24
+ // a construction-time config error. Swallowing it would silently disable
25
+ // self-verification and route self-issued credentials to a JWKS fetch on the
26
+ // worker's own hostname — which Cloudflare forbids — turning a config bug
27
+ // into an opaque per-call failure.
28
+ const selfIssuer = canonicalizeServingUrl(config.issuer);
29
+ // TODO(cache): Re-add JWKS caching with a short TTL or kid-miss retry.
30
+ // A prior implementation cached `createRemoteJWKSet` per issuer URL
31
+ // indefinitely. jose's internal cache (30s cooldown, 10min max-age) caused
32
+ // stale keys when the issuer restarted — the resolver served old keys and
33
+ // jose refused to refetch within the cooldown window. On CF Workers the
34
+ // module-level Map persisted across requests, making it worse. For now we
35
+ // create a fresh resolver per call (jose deduplicates concurrent fetches).
36
+ return async (issuer, _method, _kid) => {
37
+ const url = issuer;
38
+ // Self-issued credential (iss == this worker's own serving URL): resolve
39
+ // from the in-memory public key. Never fetch self — Cloudflare forbids a
40
+ // Worker fetching its own hostname, and the published JWKS is this key.
41
+ if (selfIssuer !== undefined) {
42
+ let canonical;
43
+ try {
44
+ canonical = canonicalizeServingUrl(url);
45
+ }
46
+ catch {
47
+ canonical = undefined;
48
+ }
49
+ if (canonical === selfIssuer) {
50
+ return createLocalJWKSet({ keys: [derivePublicJwk(config.privateKey)] });
51
+ }
52
+ }
53
+ // M-28 fix: a bare-slug iss (`mails.localhost`) makes
54
+ // `new URL('mails.localhost/.well-known/jwks.json')` throw "Invalid
55
+ // URL string". The dispatcher's identity map normalizes the iss it
56
+ // signs with, but inbound creds from older clients may still carry
57
+ // the slug form. Coerce to a URL with a default `https://` scheme
58
+ // (matches kernel.astrale.ai canonical form). If the actual receiver
59
+ // is on http://localhost the receiver-side resolver still works
60
+ // because both endpoints are on localhost — but for prod targets
61
+ // requiring TLS this is the right default.
62
+ const normalized = /^https?:\/\//.test(url) ? url : `https://${url}`;
63
+ return createRemoteJWKSet(new URL(`${normalized}/.well-known/jwks.json`));
64
+ };
65
+ }
66
+ /**
67
+ * Verify an inbound delegation credential using kernel-core's verification.
68
+ *
69
+ * @throws AuthenticationError subclasses from kernel-core on verification failure
70
+ */
71
+ export async function verifyInboundCredential(credential, config) {
72
+ // Verify using kernel-core's credential verification pipeline
73
+ const verified = await verifyCredential({
74
+ methodResolver,
75
+ resolveKeys: makeResolveKeys(config),
76
+ }, credential);
77
+ // Validate audience matches this function's issuer (its serving URL).
78
+ // kernel-core's verifyAudience compares canonically.
79
+ verifyAudience(verified, config.issuer);
80
+ // Extract attestation and delegation from claims
81
+ const attestation = verified.claims.attestation;
82
+ if (!attestation?.expr) {
83
+ throw new Error('Credential missing attestation');
84
+ }
85
+ const delegation = verified.claims.delegation;
86
+ if (!delegation?.credential) {
87
+ throw new Error('Credential missing delegation');
88
+ }
89
+ return {
90
+ verified,
91
+ issuer: verified.iss,
92
+ attestation,
93
+ delegation,
94
+ };
95
+ }
96
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/auth/verify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { defineView } from './view';
2
+ export type { ViewDef, ViewRenderContext } from './view';
3
+ export { defineRemoteFunction } from './remote-function';
4
+ export type { AnyRemoteFunctionDef, RemoteFunctionContext, RemoteFunctionDef, } from './remote-function';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/define/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA;AAExD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,YAAY,EACV,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { defineView } from './view';
2
+ export { defineRemoteFunction } from './remote-function';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/define/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAGnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Authoring a standalone remote function — a callable not bound to a class.
3
+ * (The verb keeps the `defineRemoteFunction` name; the node it materializes is
4
+ * the canonical kernel `Function` class, the former distribution `RemoteFunction`.)
5
+ *
6
+ * Each entry in `defineRemoteDomain({ remoteFunctions: { ... } })` becomes:
7
+ * - a graph node at `/${origin}/core/<functionsFolder>/<slug>`, materialized
8
+ * as the kernel `Function` class by `buildCorePath` so kernel discovery /
9
+ * `View.resolve` can list it. The `core/` anchor appears in the GRAPH path only.
10
+ * - a Hono route on the worker at the path implied by `binding`
11
+ * (`/<functionsFolder>/<slug>` POST by default — no `core/` in the URL).
12
+ *
13
+ * The slug = the map key (single source of truth, no duplication).
14
+ *
15
+ * `ref` is auto-derived as `function.<slug>` if omitted — used as
16
+ * `Function.ref` on the graph node and as the dispatch key.
17
+ */
18
+ import type { AuthPolicy, FunctionBinding } from '@astrale-os/kernel-api/routed';
19
+ import type { FnMap } from '@astrale-os/kernel-client';
20
+ import type { BoundClientSessionView } from '@astrale-os/kernel-client/session';
21
+ import type { AuthContext } from '@astrale-os/kernel-core';
22
+ import type { Context } from 'hono';
23
+ import type { z } from 'zod';
24
+ import type { CallRemoteFn } from '../dispatch/call-remote';
25
+ export type RemoteFunctionContext<TParams, TDeps = unknown> = {
26
+ /** Validated params (Zod-checked against `inputSchema`). */
27
+ params: TParams;
28
+ /** Hono request context — escape hatch for headers, raw body, etc. */
29
+ c: Context;
30
+ /** Resolved auth context. `null` when `auth: 'public'` or absent. */
31
+ auth: AuthContext | null;
32
+ /** Typed dependency container injected at server startup. */
33
+ deps: TDeps;
34
+ /**
35
+ * `BoundClientSessionView` to the parent kernel, bound to the composed
36
+ * credential `union(delegation, self)` — same shape as `RemoteContext.kernel`
37
+ * for `remoteMethod`. `null` when `auth: 'public'`, or `auth: 'optional'`
38
+ * with no inbound credential.
39
+ */
40
+ kernel: BoundClientSessionView<FnMap> | null;
41
+ /**
42
+ * Call another worker's remote method, re-minting the credential for the
43
+ * target's audience. Same contract as {@link RemoteContext.callRemote}: throws
44
+ * on a public/unauthenticated request; needs `USE` on
45
+ * `Identity.mintDelegationCredential` + the target method's grants.
46
+ */
47
+ callRemote: CallRemoteFn;
48
+ /**
49
+ * Acquire a kernel session authenticated as THIS FUNCTION'S OWN identity —
50
+ * authority = the function's own grants only, no caller delegation. The
51
+ * webhook seam: when an `auth: 'public'` upstream can't carry an Astrale
52
+ * token (HMAC-signature webhooks, Stripe-style), VERIFY THE UPSTREAM'S
53
+ * SIGNATURE FIRST, then act on the graph as yourself. `kernelUrl` defaults
54
+ * to `deps.KERNEL_URL` (set automatically on managed deploys); pass it
55
+ * explicitly for other targets.
56
+ */
57
+ selfKernel: (kernelUrl?: string) => Promise<BoundClientSessionView<FnMap>>;
58
+ };
59
+ export type RemoteFunctionDef<TParams = unknown, TResult = unknown, TDeps = unknown> = {
60
+ /**
61
+ * Canonical callable identity. Auto-derived as `function.<slug>` (where
62
+ * `<slug>` is the map key) when omitted. Stored as `Function.ref` on the
63
+ * graph node and used by the kernel dispatcher to route the call.
64
+ */
65
+ ref?: string;
66
+ /** Zod schema for the call's parameters. */
67
+ inputSchema: z.ZodType<TParams>;
68
+ /** Zod schema for the call's result. */
69
+ outputSchema: z.ZodType<TResult>;
70
+ /**
71
+ * Override the binding (URL + route shape). When absent, SDK defaults to
72
+ * `{ remoteUrl: ${url}/<functionsFolder>/<slug> }`. The HTTP verb (POST
73
+ * for functions) is applied by the worker route mounter at mount time — it is
74
+ * NOT stored on the binding, so the materialized `Function.binding` carries
75
+ * `remoteUrl` only.
76
+ *
77
+ * Use this to bind to a custom host or REST-style path. Host + path
78
+ * placeholders both supported.
79
+ */
80
+ binding?: FunctionBinding;
81
+ /** Authentication policy. Defaults to `'required'`. */
82
+ auth?: AuthPolicy;
83
+ /** Optional pre-execute authorization. Throw to deny. */
84
+ authorize?: (ctx: RemoteFunctionContext<TParams, TDeps>) => void | Promise<void>;
85
+ /** The function body. May be async. */
86
+ execute: (ctx: RemoteFunctionContext<TParams, TDeps>) => TResult | Promise<TResult>;
87
+ /** Optional human-readable description. */
88
+ description?: string;
89
+ };
90
+ export type AnyRemoteFunctionDef = RemoteFunctionDef<any, any, any>;
91
+ /**
92
+ * Identity helper for authoring a RemoteFunction. Returns its argument
93
+ * unchanged — `defineRemoteDomain` consumes the typed shape.
94
+ */
95
+ export declare function defineRemoteFunction<TParams, TResult, TDeps = unknown>(def: RemoteFunctionDef<TParams, TResult, TDeps>): RemoteFunctionDef<TParams, TResult, TDeps>;
96
+ //# sourceMappingURL=remote-function.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-function.d.ts","sourceRoot":"","sources":["../../src/define/remote-function.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAChF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAA;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAA;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAE3D,MAAM,MAAM,qBAAqB,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,IAAI;IAC5D,4DAA4D;IAC5D,MAAM,EAAE,OAAO,CAAA;IACf,sEAAsE;IACtE,CAAC,EAAE,OAAO,CAAA;IACV,qEAAqE;IACrE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;IACxB,6DAA6D;IAC7D,IAAI,EAAE,KAAK,CAAA;IACX;;;;;OAKG;IACH,MAAM,EAAE,sBAAsB,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;IAC5C;;;;;OAKG;IACH,UAAU,EAAE,YAAY,CAAA;IACxB;;;;;;;;OAQG;IACH,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAA;CAC3E,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO,IAAI;IACrF;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,4CAA4C;IAC5C,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/B,wCAAwC;IACxC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAChC;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,uDAAuD;IACvD,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,yDAAyD;IACzD,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChF,uCAAuC;IACvC,OAAO,EAAE,CAAC,GAAG,EAAE,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACnF,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAGD,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAEnE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,OAAO,EACpE,GAAG,EAAE,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,GAC9C,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAE5C"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Authoring a standalone remote function — a callable not bound to a class.
3
+ * (The verb keeps the `defineRemoteFunction` name; the node it materializes is
4
+ * the canonical kernel `Function` class, the former distribution `RemoteFunction`.)
5
+ *
6
+ * Each entry in `defineRemoteDomain({ remoteFunctions: { ... } })` becomes:
7
+ * - a graph node at `/${origin}/core/<functionsFolder>/<slug>`, materialized
8
+ * as the kernel `Function` class by `buildCorePath` so kernel discovery /
9
+ * `View.resolve` can list it. The `core/` anchor appears in the GRAPH path only.
10
+ * - a Hono route on the worker at the path implied by `binding`
11
+ * (`/<functionsFolder>/<slug>` POST by default — no `core/` in the URL).
12
+ *
13
+ * The slug = the map key (single source of truth, no duplication).
14
+ *
15
+ * `ref` is auto-derived as `function.<slug>` if omitted — used as
16
+ * `Function.ref` on the graph node and as the dispatch key.
17
+ */
18
+ /**
19
+ * Identity helper for authoring a RemoteFunction. Returns its argument
20
+ * unchanged — `defineRemoteDomain` consumes the typed shape.
21
+ */
22
+ export function defineRemoteFunction(def) {
23
+ return def;
24
+ }
25
+ //# sourceMappingURL=remote-function.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-function.js","sourceRoot":"","sources":["../../src/define/remote-function.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAiFH;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAA+C;IAE/C,OAAO,GAAG,CAAA;AACZ,CAAC"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Authoring a `View` — iframe-mountable callable served by the domain worker.
3
+ *
4
+ * Each entry in `defineRemoteDomain({ views: { ... } })` becomes both:
5
+ * - a graph node at `/${origin}/core/<viewsFolder>/<slug>` (auto-materialized
6
+ * by the SDK; the `core/` segment is the universal anchor injected by
7
+ * `buildCorePath`. `<slug>` is the map key, so it lives in exactly one place)
8
+ * - a Hono route on the worker at the path implied by `binding`
9
+ * (`/<viewsFolder>/<slug>` by default — note: no `core/` in the URL).
10
+ *
11
+ * The `core/` segment appears in the GRAPH path only; the URL path that
12
+ * lands in `Function.binding.remoteUrl` is `${url}/<viewsFolder>/<slug>`.
13
+ *
14
+ * The author can override the URL via `binding` — host and/or path
15
+ * placeholders are supported (the kernel's `route` mechanism does the
16
+ * substitution + Hono matching, same as for methods). When `render` is
17
+ * omitted, no worker route is mounted — useful for Views whose iframe
18
+ * lives at an external host.
19
+ */
20
+ import type { AuthPolicy, FunctionBinding } from '@astrale-os/kernel-api/routed';
21
+ import type { AuthContext } from '@astrale-os/kernel-core';
22
+ import type { EdgeEndpoint } from '@astrale-os/kernel-dsl';
23
+ import type { Context } from 'hono';
24
+ export type ViewRenderContext<TDeps = unknown> = {
25
+ /** Hono request context — read params, headers, query, etc. */
26
+ c: Context;
27
+ /**
28
+ * Placeholders extracted from the request URL (host + path placeholders
29
+ * declared in `binding.remoteUrl` / `binding.route.path`). Empty when
30
+ * the binding has no placeholders.
31
+ */
32
+ params: Record<string, string>;
33
+ /** Resolved auth context. `null` when `auth: 'public'` or absent. */
34
+ auth: AuthContext | null;
35
+ /** Typed dependency container injected at server startup. */
36
+ deps: TDeps;
37
+ };
38
+ export type ViewDef<TDeps = unknown> = {
39
+ /**
40
+ * Override the binding (URL + route shape). When absent, SDK defaults to
41
+ * `{ remoteUrl: ${url}/<viewsFolder>/<slug> }`. The HTTP verb (GET for
42
+ * views) is applied by the worker route mounter at mount time — it is NOT
43
+ * stored on the binding.
44
+ *
45
+ * Use this to bind to a custom host (e.g. `https://{tenant}.example.com`)
46
+ * or REST-style path. Host + path placeholders both supported.
47
+ */
48
+ binding?: FunctionBinding;
49
+ /**
50
+ * Worker-relative path the View's iframe is served from (e.g. `'/ui/note'`),
51
+ * for Views backed by the client SPA instead of a `render`. The spec producer
52
+ * resolves it against the serving url (`binding.remoteUrl = ${url}${mount}`)
53
+ * at materialize time — so the dev never hardcodes a URL. Mutually exclusive
54
+ * with `render`; takes precedence over `binding`.
55
+ */
56
+ mount?: string;
57
+ /** Authentication policy. Defaults to `'required'`. */
58
+ auth?: AuthPolicy;
59
+ /**
60
+ * Optional pre-render authorization. Runs after auth resolution; throw to
61
+ * deny. SDK wraps as 403.
62
+ */
63
+ authorize?: (ctx: ViewRenderContext<TDeps>) => void | Promise<void>;
64
+ /**
65
+ * Render the iframe response. May return a redirect, a proxy, or inline
66
+ * HTML. When omitted, no worker route is mounted — the binding URL
67
+ * points elsewhere (CDN, external service).
68
+ */
69
+ render?: (ctx: ViewRenderContext<TDeps>) => Response | Promise<Response>;
70
+ /**
71
+ * Optional target(s) the View attaches to via `view_for` edge(s). Typically
72
+ * `selfOf(SomeClass)` to bind to a class meta-node, or a `CorePath`
73
+ * pointing at a specific instance. Pass an array to attach the same View
74
+ * to multiple targets (one `view_for` edge is materialized per entry).
75
+ */
76
+ viewFor?: EdgeEndpoint | EdgeEndpoint[];
77
+ /** Optional human-readable description. */
78
+ description?: string;
79
+ };
80
+ /**
81
+ * Identity helper for authoring a View. Returns its argument unchanged —
82
+ * `defineRemoteDomain` consumes the typed shape and the author retains
83
+ * full type inference on `render` / `authorize`.
84
+ */
85
+ export declare function defineView<TDeps = unknown>(def: ViewDef<TDeps>): ViewDef<TDeps>;
86
+ //# sourceMappingURL=view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/define/view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAChF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAEnC,MAAM,MAAM,iBAAiB,CAAC,KAAK,GAAG,OAAO,IAAI;IAC/C,+DAA+D;IAC/D,CAAC,EAAE,OAAO,CAAA;IACV;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,qEAAqE;IACrE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;IACxB,6DAA6D;IAC7D,IAAI,EAAE,KAAK,CAAA;CACZ,CAAA;AAED,MAAM,MAAM,OAAO,CAAC,KAAK,GAAG,OAAO,IAAI;IACrC;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnE;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACxE;;;;;OAKG;IACH,OAAO,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;IACvC,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,GAAG,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAE/E"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Authoring a `View` — iframe-mountable callable served by the domain worker.
3
+ *
4
+ * Each entry in `defineRemoteDomain({ views: { ... } })` becomes both:
5
+ * - a graph node at `/${origin}/core/<viewsFolder>/<slug>` (auto-materialized
6
+ * by the SDK; the `core/` segment is the universal anchor injected by
7
+ * `buildCorePath`. `<slug>` is the map key, so it lives in exactly one place)
8
+ * - a Hono route on the worker at the path implied by `binding`
9
+ * (`/<viewsFolder>/<slug>` by default — note: no `core/` in the URL).
10
+ *
11
+ * The `core/` segment appears in the GRAPH path only; the URL path that
12
+ * lands in `Function.binding.remoteUrl` is `${url}/<viewsFolder>/<slug>`.
13
+ *
14
+ * The author can override the URL via `binding` — host and/or path
15
+ * placeholders are supported (the kernel's `route` mechanism does the
16
+ * substitution + Hono matching, same as for methods). When `render` is
17
+ * omitted, no worker route is mounted — useful for Views whose iframe
18
+ * lives at an external host.
19
+ */
20
+ /**
21
+ * Identity helper for authoring a View. Returns its argument unchanged —
22
+ * `defineRemoteDomain` consumes the typed shape and the author retains
23
+ * full type inference on `render` / `authorize`.
24
+ */
25
+ export function defineView(def) {
26
+ return def;
27
+ }
28
+ //# sourceMappingURL=view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.js","sourceRoot":"","sources":["../../src/define/view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAiEH;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAkB,GAAmB;IAC7D,OAAO,GAAG,CAAA;AACZ,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { Meta } from './meta';
2
+ export type DeployCheckOptions = {
3
+ /** Deployed worker URL (e.g. `https://dist.astrale.ai`). */
4
+ url: string;
5
+ /**
6
+ * Expected `meta.schemaHash` — the hash of the locally-built `spec.json`
7
+ * (via `hashSpecFile`). REQUIRED to verify schema drift: when the worker
8
+ * advertises a `schemaHash` but this is absent, the check fails loudly rather
9
+ * than silently "passing" an unverified deploy. Per-domain deploy scripts
10
+ * compute it (`hashSpecFile('./spec.json')`) and pass it.
11
+ */
12
+ expectedSchemaHash?: string;
13
+ /**
14
+ * Path to the SDK repo used to read `sdkCommit`. If omitted and
15
+ * `workspaceRoot` is provided, defaults to `<workspaceRoot>/sdk`.
16
+ */
17
+ sdkRepoPath?: string;
18
+ /** Astrale workspace root — enables auto-resolution of `sdkRepoPath` (`<root>/sdk`). */
19
+ workspaceRoot?: string;
20
+ /** Sink for progress output. Defaults to `console.log`. */
21
+ log?: (line: string) => void;
22
+ };
23
+ /**
24
+ * Validate a deployed worker against local state by fetching `/meta` and
25
+ * verifying sdkCommit / schemaHash / JWKS reachability.
26
+ *
27
+ * Throws on any mismatch. Returns `Meta` on success.
28
+ */
29
+ export declare function deployCheck(opts: DeployCheckOptions): Promise<Meta>;
30
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/deploy/check.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAIlC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAA;IACX;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,wFAAwF;IACxF,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,2DAA2D;IAC3D,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7B,CAAA;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBzE"}
@@ -0,0 +1,82 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { join } from 'node:path';
3
+ import { MetaSchema } from './meta';
4
+ /**
5
+ * Validate a deployed worker against local state by fetching `/meta` and
6
+ * verifying sdkCommit / schemaHash / JWKS reachability.
7
+ *
8
+ * Throws on any mismatch. Returns `Meta` on success.
9
+ */
10
+ export async function deployCheck(opts) {
11
+ // oxlint-disable-next-line no-console
12
+ const log = opts.log ?? ((line) => console.log(line));
13
+ const base = opts.url.replace(/\/+$/, '');
14
+ log(`# deploy:check ${base}`);
15
+ const meta = await fetchMeta(base);
16
+ log(` meta: ${JSON.stringify(meta)}`);
17
+ // `meta.iss` is required + non-empty by `MetaSchema`, enforced in `fetchMeta`.
18
+ await Promise.all([
19
+ checkSdkCommit(meta, opts, log),
20
+ checkSchemaHash(meta, opts, log),
21
+ checkJwks(meta.iss, log),
22
+ ]);
23
+ return meta;
24
+ }
25
+ async function fetchMeta(base) {
26
+ const res = await fetch(`${base}/meta`);
27
+ if (!res.ok)
28
+ throw new Error(`GET ${base}/meta → ${res.status}`);
29
+ return MetaSchema.parse(await res.json());
30
+ }
31
+ async function checkSdkCommit(meta, opts, log) {
32
+ if (!meta.sdkCommit) {
33
+ log(' ! meta.sdkCommit absent — skipping sdkCommit check');
34
+ return;
35
+ }
36
+ const sdkRepo = opts.sdkRepoPath ?? (opts.workspaceRoot ? join(opts.workspaceRoot, 'sdk') : undefined);
37
+ if (!sdkRepo) {
38
+ log(` ! no sdkRepoPath / workspaceRoot — skipping sdkCommit check`);
39
+ return;
40
+ }
41
+ const localSha = gitHead(sdkRepo);
42
+ if (!localSha) {
43
+ log(` ! could not read git HEAD from ${sdkRepo} — skipping sdkCommit check`);
44
+ return;
45
+ }
46
+ if (!localSha.startsWith(meta.sdkCommit) && !meta.sdkCommit.startsWith(localSha)) {
47
+ throw new Error(`sdkCommit mismatch: deployed=${meta.sdkCommit} local=${localSha} (${sdkRepo})`);
48
+ }
49
+ log(` ✓ sdkCommit ${meta.sdkCommit} matches local HEAD`);
50
+ }
51
+ async function checkSchemaHash(meta, opts, log) {
52
+ if (!meta.schemaHash)
53
+ return;
54
+ // Fail loud: the worker advertises a schemaHash, so a missing expected value
55
+ // means we CANNOT verify drift — never silently "pass" an unverified deploy.
56
+ if (!opts.expectedSchemaHash) {
57
+ throw new Error(`worker advertises schemaHash=${meta.schemaHash} but no expectedSchemaHash was provided — ` +
58
+ `cannot verify schema drift (pass expectedSchemaHash, e.g. hashSpecFile('./spec.json'))`);
59
+ }
60
+ if (meta.schemaHash !== opts.expectedSchemaHash) {
61
+ throw new Error(`schemaHash mismatch: deployed=${meta.schemaHash} local=${opts.expectedSchemaHash}`);
62
+ }
63
+ log(` ✓ schemaHash ${meta.schemaHash} matches local`);
64
+ }
65
+ async function checkJwks(iss, log) {
66
+ const jwksUrl = `${iss.replace(/\/+$/, '')}/.well-known/jwks.json`;
67
+ const res = await fetch(jwksUrl);
68
+ if (!res.ok)
69
+ throw new Error(`GET ${jwksUrl} → ${res.status}`);
70
+ const body = (await res.json());
71
+ const keys = body.keys ?? [];
72
+ if (keys.length === 0)
73
+ throw new Error(`${jwksUrl} returned no keys`);
74
+ log(` ✓ JWKS resolves (${keys.length} key${keys.length === 1 ? '' : 's'})`);
75
+ }
76
+ function gitHead(repoPath) {
77
+ const r = spawnSync('git', ['-C', repoPath, 'rev-parse', 'HEAD'], { encoding: 'utf-8' });
78
+ if (r.status !== 0)
79
+ return null;
80
+ return r.stdout.trim();
81
+ }
82
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/deploy/check.ts"],"names":[],"mappings":"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"}