@gnomondigital/nebulas-kit-core 0.2.1 → 0.3.1

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.
@@ -7,6 +7,5 @@
7
7
  */
8
8
  export declare function sendMessageStream(message: string, onDelta: (chunk: string) => void, signal?: AbortSignal, files?: File[], stream?: boolean, sessionId?: string, options?: {
9
9
  endpoint?: string;
10
- getHeaders?: () => Promise<Record<string, string>>;
11
10
  }): Promise<string>;
12
11
  //# sourceMappingURL=a2a-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"a2a-client.d.ts","sourceRoot":"","sources":["../src/a2a-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAChC,MAAM,CAAC,EAAE,WAAW,EACpB,KAAK,CAAC,EAAE,IAAI,EAAE,EACd,MAAM,UAAO,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAAE,GAClF,OAAO,CAAC,MAAM,CAAC,CAgIjB"}
1
+ {"version":3,"file":"a2a-client.d.ts","sourceRoot":"","sources":["../src/a2a-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAChC,MAAM,CAAC,EAAE,WAAW,EACpB,KAAK,CAAC,EAAE,IAAI,EAAE,EACd,MAAM,UAAO,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC7B,GACA,OAAO,CAAC,MAAM,CAAC,CA4HjB"}
@@ -33,10 +33,6 @@ export async function sendMessageStream(message, onDelta, signal, files, stream
33
33
  const method = stream ? "message/stream" : "message/send";
34
34
  const messageId = crypto.randomUUID();
35
35
  const headers = { "Content-Type": "application/json" };
36
- if (options?.getHeaders) {
37
- const extra = await options.getHeaders();
38
- Object.assign(headers, extra);
39
- }
40
36
  const res = await fetch(endpoint, {
41
37
  method: "POST",
42
38
  headers,
package/dist/index.d.ts CHANGED
@@ -11,6 +11,6 @@ export { getAuthStrategy, getAuthHeaders, type AuthStrategy, } from "./server/au
11
11
  export { exchangePasswordForToken, type ROPAuthRequest, type ROPAuthResponse, } from "./server/auth-handler.js";
12
12
  export { createConfigResponse, type ConfigResponse, type AgentCard, type AgentCardCapabilities, } from "./server/config-handler.js";
13
13
  export { createA2AExpressRouter, type A2AExpressRouterOptions, } from "./server/express.js";
14
- export { handleA2ANextJsPOST, handleA2AAuthNextJsPOST, handleA2AConfigNextJsGET, createConfigGetHeadersForAuth0, createNebulasProxyHandler, type HandleA2AConfigOptions, type Auth0ClientForConfig, type CreateNebulasProxyHandlerOptions, } from "./server/nextjs.js";
14
+ export { handleA2ANextJsPOST, handleA2AAuthNextJsPOST, handleA2AConfigNextJsGET, createGetHeadersForAuth0, createA2AProxyHandler, createNebulasProxyHandler, type HandleA2AConfigOptions, type Auth0ClientInterface, type CreateA2AProxyHandlerOptions, type CreateNebulasProxyHandlerOptions, } from "./server/nextjs.js";
15
15
  export { handleNebulasProxy, isRefreshTokenInvalid, type NebulasProxyRequest, type NebulasProxyResponse, type NebulasProxyHandlerOptions, } from "./server/nebulas-proxy-handler.js";
16
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE5F,OAAO,EACL,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,mBAAmB,GACzB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,eAAe,EACf,cAAc,EACd,KAAK,YAAY,GAClB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,wBAAwB,EACxB,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,qBAAqB,GAC3B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,sBAAsB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,EACxB,8BAA8B,EAC9B,yBAAyB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,gCAAgC,GACtC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAChC,MAAM,mCAAmC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE5F,OAAO,EACL,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,mBAAmB,GACzB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,eAAe,EACf,cAAc,EACd,KAAK,YAAY,GAClB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,wBAAwB,EACxB,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,qBAAqB,GAC3B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,sBAAsB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,gCAAgC,GACtC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAChC,MAAM,mCAAmC,CAAC"}
package/dist/index.js CHANGED
@@ -11,5 +11,5 @@ export { exchangePasswordForToken, } from "./server/auth-handler.js";
11
11
  export { createConfigResponse, } from "./server/config-handler.js";
12
12
  export { createA2AExpressRouter, } from "./server/express.js";
13
13
  // Usage: import express from "express"; app.use("/api/a2a", createA2AExpressRouter(express));
14
- export { handleA2ANextJsPOST, handleA2AAuthNextJsPOST, handleA2AConfigNextJsGET, createConfigGetHeadersForAuth0, createNebulasProxyHandler, } from "./server/nextjs.js";
14
+ export { handleA2ANextJsPOST, handleA2AAuthNextJsPOST, handleA2AConfigNextJsGET, createGetHeadersForAuth0, createA2AProxyHandler, createNebulasProxyHandler, } from "./server/nextjs.js";
15
15
  export { handleNebulasProxy, isRefreshTokenInvalid, } from "./server/nebulas-proxy-handler.js";
@@ -3,7 +3,7 @@
3
3
  * Fetches agent card from A2A_URL/.well-known/agent-card.json when A2A_URL is set.
4
4
  * Framework-agnostic; returns JSON response body.
5
5
  */
6
- const A2A_URL = process.env.NEXT_PUBLIC_A2A_URL || process.env.A2A_URL || "";
6
+ const A2A_URL = process.env.A2A_URL || process.env.NEXT_PUBLIC_A2A_URL || "";
7
7
  async function fetchAgentCard(headers) {
8
8
  const base = A2A_URL.replace(/\/$/, "");
9
9
  if (!base)
@@ -19,7 +19,7 @@ export declare function handleA2AAuthNextJsPOST(request: NextRequest): Promise<R
19
19
  export interface HandleA2AConfigOptions {
20
20
  /**
21
21
  * When provided, fetches the agent card with these headers (Authorization, x-api-key).
22
- * Use createConfigGetHeadersForAuth0 for Auth0 session strategy.
22
+ * Use createGetHeadersForAuth0 for Auth0 session strategy.
23
23
  */
24
24
  getHeaders?: (request: NextRequest) => Promise<Record<string, string>>;
25
25
  }
@@ -32,7 +32,7 @@ export declare function handleA2AConfigNextJsGET(request: NextRequest, options?:
32
32
  * Auth0 client interface for config headers.
33
33
  * Compatible with Auth0Client from @auth0/nextjs-auth0/server.
34
34
  */
35
- export interface Auth0ClientForConfig {
35
+ export interface Auth0ClientInterface {
36
36
  getSession(req: unknown): Promise<{
37
37
  user?: unknown;
38
38
  } | null>;
@@ -43,20 +43,40 @@ export interface Auth0ClientForConfig {
43
43
  }>;
44
44
  }
45
45
  /**
46
- * Creates getHeaders for handleA2AConfigNextJsGET using Auth0 session.
47
- * Uses same auth as A2A proxy: session, access token for A2A audience, x-api-key fallback.
46
+ * Creates getHeaders for handleA2AConfigNextJsGET and createA2AProxyHandler using Auth0 session.
47
+ * Uses same auth: session, access token for A2A audience, x-api-key fallback.
48
48
  * Throws NextResponse (401) when unauthorized.
49
+ *
50
+ * @param authResponse - When provided (e.g. by A2A proxy), getAccessToken uses it so caller can propagate Set-Cookie from token refresh.
51
+ */
52
+ export declare function createGetHeadersForAuth0(options: {
53
+ auth0: Auth0ClientInterface;
54
+ audience?: string;
55
+ apiKey?: string;
56
+ }): (request: NextRequest, authResponse?: NextResponse) => Promise<Record<string, string>>;
57
+ /**
58
+ * Options for the A2A proxy handler with Auth0 session.
49
59
  */
50
- export declare function createConfigGetHeadersForAuth0(options: {
51
- auth0: Auth0ClientForConfig;
60
+ export interface CreateA2AProxyHandlerOptions {
61
+ auth0: Auth0ClientInterface;
52
62
  audience?: string;
53
63
  apiKey?: string;
54
- }): (request: NextRequest) => Promise<Record<string, string>>;
64
+ }
65
+ /**
66
+ * Creates a Next.js App Router POST handler for the A2A proxy.
67
+ * Proxies requests to A2A_URL with Auth0 session token or API key.
68
+ * Propagates Set-Cookie from Auth0 token refresh.
69
+ *
70
+ * Use in app/api/a2a/route.ts:
71
+ * const handler = createA2AProxyHandler({ auth0, audience: process.env.AUTH0_A2A_AUDIENCE, apiKey: process.env.A2A_API_KEY });
72
+ * export const POST = handler;
73
+ */
74
+ export declare function createA2AProxyHandler(options: CreateA2AProxyHandlerOptions): (request: NextRequest) => Promise<Response>;
55
75
  /**
56
76
  * Options for the Nebulas API proxy handler.
57
77
  */
58
78
  export interface CreateNebulasProxyHandlerOptions {
59
- auth0: Auth0ClientForConfig;
79
+ auth0: Auth0ClientInterface;
60
80
  audience?: string;
61
81
  apiKey?: string;
62
82
  }
@@ -1 +1 @@
1
- {"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../../src/server/nextjs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAiB9E;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,mBAAmB,qBA6B9B;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,WAAW,qBAyBjE;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACxE;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,sBAAsB,qBAcjC;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC7D,cAAc,CACZ,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GACzB,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE;IACtD,KAAK,EAAE,oBAAoB,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAyC5D;AAED;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,KAAK,EAAE,oBAAoB,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gCAAgC,IAE/E,SAAS,WAAW,EACpB,KAAK;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE,oCAkH/C"}
1
+ {"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../../src/server/nextjs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAiB9E;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,mBAAmB,qBA6B9B;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,WAAW,qBAyBjE;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACxE;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,sBAAsB,qBAcjC;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC7D,cAAc,CACZ,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GACzB,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,KAAK,EAAE,oBAAoB,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,CACF,OAAO,EAAE,WAAW,EACpB,YAAY,CAAC,EAAE,YAAY,KACxB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAoDnC;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,oBAAoB,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,IAO3C,SAAS,WAAW,uBAuDnD;AAED;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,KAAK,EAAE,oBAAoB,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gCAAgC,IAE/E,SAAS,WAAW,EACpB,KAAK;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE,oCAkH/C"}
@@ -85,12 +85,14 @@ export async function handleA2AConfigNextJsGET(request, options) {
85
85
  });
86
86
  }
87
87
  /**
88
- * Creates getHeaders for handleA2AConfigNextJsGET using Auth0 session.
89
- * Uses same auth as A2A proxy: session, access token for A2A audience, x-api-key fallback.
88
+ * Creates getHeaders for handleA2AConfigNextJsGET and createA2AProxyHandler using Auth0 session.
89
+ * Uses same auth: session, access token for A2A audience, x-api-key fallback.
90
90
  * Throws NextResponse (401) when unauthorized.
91
+ *
92
+ * @param authResponse - When provided (e.g. by A2A proxy), getAccessToken uses it so caller can propagate Set-Cookie from token refresh.
91
93
  */
92
- export function createConfigGetHeadersForAuth0(options) {
93
- return async (request) => {
94
+ export function createGetHeadersForAuth0(options) {
95
+ return async (request, authResponse) => {
94
96
  const session = await options.auth0.getSession(request);
95
97
  if (!session) {
96
98
  throw new NextResponse(JSON.stringify({ error: "Unauthorized" }), {
@@ -104,8 +106,8 @@ export function createConfigGetHeadersForAuth0(options) {
104
106
  }
105
107
  if (options.audience) {
106
108
  try {
107
- const authResponse = new NextResponse();
108
- const { token } = await options.auth0.getAccessToken(request, authResponse, {
109
+ const res = authResponse ?? new NextResponse();
110
+ const { token } = await options.auth0.getAccessToken(request, res, {
109
111
  audience: options.audience,
110
112
  });
111
113
  if (token) {
@@ -114,6 +116,13 @@ export function createConfigGetHeadersForAuth0(options) {
114
116
  }
115
117
  catch (err) {
116
118
  console.error("[Config] Failed to get access token:", err);
119
+ if (isRefreshTokenInvalid(err)) {
120
+ throw new NextResponse(JSON.stringify({
121
+ error: "Your session has expired. Please log out and log back in.",
122
+ code: "refresh_token_invalid",
123
+ requireReauth: true,
124
+ }), { status: 401, headers: { "Content-Type": "application/json" } });
125
+ }
117
126
  if (!options.apiKey) {
118
127
  throw new NextResponse(JSON.stringify({
119
128
  error: "Unauthorized",
@@ -125,6 +134,71 @@ export function createConfigGetHeadersForAuth0(options) {
125
134
  return headers;
126
135
  };
127
136
  }
137
+ /**
138
+ * Creates a Next.js App Router POST handler for the A2A proxy.
139
+ * Proxies requests to A2A_URL with Auth0 session token or API key.
140
+ * Propagates Set-Cookie from Auth0 token refresh.
141
+ *
142
+ * Use in app/api/a2a/route.ts:
143
+ * const handler = createA2AProxyHandler({ auth0, audience: process.env.AUTH0_A2A_AUDIENCE, apiKey: process.env.A2A_API_KEY });
144
+ * export const POST = handler;
145
+ */
146
+ export function createA2AProxyHandler(options) {
147
+ const getHeaders = createGetHeadersForAuth0({
148
+ auth0: options.auth0,
149
+ audience: options.audience,
150
+ apiKey: options.apiKey,
151
+ });
152
+ return async function handler(request) {
153
+ let authHeaders;
154
+ const authResponse = new NextResponse();
155
+ try {
156
+ authHeaders = await getHeaders(request, authResponse);
157
+ }
158
+ catch (err) {
159
+ if (err instanceof NextResponse) {
160
+ return err;
161
+ }
162
+ throw err;
163
+ }
164
+ let body;
165
+ try {
166
+ const text = await request.text();
167
+ body = text.length > 0 ? text : undefined;
168
+ }
169
+ catch {
170
+ return NextResponse.json({ error: "Invalid request body" }, { status: 400 });
171
+ }
172
+ const proxyReq = {
173
+ method: request.method,
174
+ headers: headersFromRequest(request),
175
+ body,
176
+ };
177
+ const result = await handleA2AProxy(proxyReq, { headers: authHeaders });
178
+ const responseHeaders = new Headers();
179
+ for (const [k, v] of Object.entries(result.headers)) {
180
+ responseHeaders.set(k, v);
181
+ }
182
+ authResponse.headers.forEach((value, key) => {
183
+ if (key.toLowerCase() === "set-cookie") {
184
+ responseHeaders.append(key, value);
185
+ }
186
+ });
187
+ if (typeof result.body === "string") {
188
+ return new Response(result.body, {
189
+ status: result.status,
190
+ headers: responseHeaders,
191
+ });
192
+ }
193
+ if (result.body instanceof ReadableStream) {
194
+ return new Response(result.body, {
195
+ status: result.status,
196
+ headers: responseHeaders,
197
+ });
198
+ }
199
+ return new Response(null, { status: result.status, headers: responseHeaders });
200
+ };
201
+ }
128
202
  /**
129
203
  * Creates a Next.js App Router handler for the Nebulas API proxy (catch-all [...path]).
130
204
  * Proxies requests to NEBULAS_API_URL with Auth0 session token or API key.
@@ -14,6 +14,11 @@ export interface ProxyResponse {
14
14
  }
15
15
  export interface ProxyHandlerOptions {
16
16
  getSessionToken?: (req: ProxyRequest) => Promise<string | undefined>;
17
+ /**
18
+ * When provided, used as auth headers instead of getAuthHeaders.
19
+ * Caller is responsible for auth (e.g. Auth0 session). Used by createA2AProxyHandler.
20
+ */
21
+ headers?: Record<string, string>;
17
22
  }
18
23
  /**
19
24
  * Handle A2A proxy request. Returns response to send.
@@ -1 +1 @@
1
- {"version":3,"file":"proxy-handler.d.ts","sourceRoot":"","sources":["../../src/server/proxy-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACtE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,YAAY,EACjB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,aAAa,CAAC,CA0ExB"}
1
+ {"version":3,"file":"proxy-handler.d.ts","sourceRoot":"","sources":["../../src/server/proxy-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACrE;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,YAAY,EACjB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,aAAa,CAAC,CAkFxB"}
@@ -3,42 +3,51 @@
3
3
  * Accepts a minimal request/response interface.
4
4
  */
5
5
  import { getAuthStrategy, getAuthHeaders, } from "./auth-strategies.js";
6
- const A2A_URL = process.env.NEXT_PUBLIC_A2A_URL || process.env.A2A_URL || "http://localhost:9999";
6
+ const A2A_URL = process.env.A2A_URL || process.env.NEXT_PUBLIC_A2A_URL || "http://localhost:9999";
7
7
  /**
8
8
  * Handle A2A proxy request. Returns response to send.
9
9
  */
10
10
  export async function handleA2AProxy(req, options = {}) {
11
11
  const url = A2A_URL.replace(/\/$/, "");
12
- const strategy = getAuthStrategy();
13
- let bearerToken;
14
- const authHeader = req.headers["authorization"] || req.headers["Authorization"];
15
- if (authHeader?.startsWith("Bearer ")) {
16
- bearerToken = authHeader.slice(7);
17
- }
18
- else if (strategy === "session" && options.getSessionToken) {
19
- bearerToken = await options.getSessionToken(req);
12
+ let headers;
13
+ if (options.headers) {
14
+ headers = {
15
+ "Content-Type": req.headers["content-type"] || "application/json",
16
+ ...options.headers,
17
+ };
20
18
  }
21
- if (strategy === "session" && !bearerToken && !process.env.A2A_API_KEY) {
22
- return {
23
- status: 401,
24
- headers: { "Content-Type": "application/json" },
25
- body: JSON.stringify({
26
- error: "Unauthorized",
27
- hint: "Session required or A2A_API_KEY for fallback.",
28
- }),
19
+ else {
20
+ const strategy = getAuthStrategy();
21
+ let bearerToken;
22
+ const authHeader = req.headers["authorization"] || req.headers["Authorization"];
23
+ if (authHeader?.startsWith("Bearer ")) {
24
+ bearerToken = authHeader.slice(7);
25
+ }
26
+ else if (strategy === "session" && options.getSessionToken) {
27
+ bearerToken = await options.getSessionToken(req);
28
+ }
29
+ if (strategy === "session" && !bearerToken && !process.env.A2A_API_KEY) {
30
+ return {
31
+ status: 401,
32
+ headers: { "Content-Type": "application/json" },
33
+ body: JSON.stringify({
34
+ error: "Unauthorized",
35
+ hint: "Session required or A2A_API_KEY for fallback.",
36
+ }),
37
+ };
38
+ }
39
+ const authHeaders = await getAuthHeaders({
40
+ strategy,
41
+ bearerToken,
42
+ getSessionToken: options.getSessionToken
43
+ ? () => options.getSessionToken(req)
44
+ : undefined,
45
+ });
46
+ headers = {
47
+ "Content-Type": req.headers["content-type"] || "application/json",
48
+ ...authHeaders,
29
49
  };
30
50
  }
31
- const authHeaders = await getAuthHeaders({
32
- strategy,
33
- bearerToken,
34
- getSessionToken: options.getSessionToken
35
- ? () => options.getSessionToken(req)
36
- : undefined,
37
- });
38
- const headers = {
39
- "Content-Type": req.headers["content-type"] || "application/json",
40
- ...authHeaders,
41
- };
42
51
  try {
43
52
  const res = await fetch(url, {
44
53
  method: req.method,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gnomondigital/nebulas-kit-core",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",