@agentuity/server 2.0.10 → 3.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
+ export { createServerFetchAdapter, buildClientHeaders, type BuildClientHeadersOptions, type ServiceAdapterConfig, redact, } from '@agentuity/adapter';
1
2
  export * from '@agentuity/core';
2
3
  export { type ColorScheme, ConsoleLogger, createLogger } from './logger.ts';
3
- export { createServerFetchAdapter, buildClientHeaders, type BuildClientHeadersOptions, } from './server.ts';
4
4
  export { toJSONSchema } from './schema.ts';
5
5
  export { getContentType, mimeTypes } from './util/mime.ts';
6
6
  export { validateCPUSpec, validateMemorySpec, validateResources, type ResourceValidationResult, type ResourcesConfig, type ValidatedResources, } from './util/resources.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,iBAAiB,CAAC;AAGhC,OAAO,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EACN,wBAAwB,EACxB,kBAAkB,EAClB,KAAK,yBAAyB,GAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EACN,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,wBAAwB,EACxB,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,MAAM,GACN,MAAM,oBAAoB,CAAC;AAK5B,cAAc,iBAAiB,CAAC;AAGhC,OAAO,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EACN,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC"}
package/dist/index.js CHANGED
@@ -1,8 +1,11 @@
1
- // Re-export ALL API modules from core (moved there for browser compatibility)
1
+ // Re-export adapter functions (backward compatibility - prefer @agentuity/adapter)
2
+ export { createServerFetchAdapter, buildClientHeaders, redact, } from '@agentuity/adapter';
3
+ // Re-export commonly used types from core
4
+ // Note: Full re-export maintained for backward compatibility with CLI and other packages
5
+ // TODO: Phase 2 - Migrate CLI imports to @agentuity/core directly, then remove this re-export
2
6
  export * from '@agentuity/core';
3
7
  // Server-specific exports (these remain in @agentuity/server only)
4
8
  export { ConsoleLogger, createLogger } from "./logger.js";
5
- export { createServerFetchAdapter, buildClientHeaders, } from "./server.js";
6
9
  export { toJSONSchema } from "./schema.js";
7
10
  export { getContentType, mimeTypes } from "./util/mime.js";
8
11
  export { validateCPUSpec, validateMemorySpec, validateResources, } from "./util/resources.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,cAAc,iBAAiB,CAAC;AAEhC,mEAAmE;AACnE,OAAO,EAAoB,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EACN,wBAAwB,EACxB,kBAAkB,GAElB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EACN,eAAe,EACf,kBAAkB,EAClB,iBAAiB,GAIjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAgC,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,OAAO,EACN,wBAAwB,EACxB,kBAAkB,EAGlB,MAAM,GACN,MAAM,oBAAoB,CAAC;AAE5B,0CAA0C;AAC1C,yFAAyF;AACzF,8FAA8F;AAC9F,cAAc,iBAAiB,CAAC;AAEhC,mEAAmE;AACnE,OAAO,EAAoB,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EACN,eAAe,EACf,kBAAkB,EAClB,iBAAiB,GAIjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAgC,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC"}
@@ -26,18 +26,14 @@ export interface RuntimeBootstrapOptions {
26
26
  * Note: This does NOT load .env files. Use a proper .env loader
27
27
  * (like dotenv) in your app.ts before calling this function.
28
28
  *
29
- * Call this BEFORE createApp() in your app.ts:
29
+ * Call this early in your app entry point:
30
30
  *
31
31
  * @example
32
32
  * ```ts
33
33
  * import { bootstrapRuntimeEnv } from '@agentuity/server';
34
- * import { createApp } from '@agentuity/runtime';
35
34
  *
36
- * // Set up service URLs
35
+ * // Set up service URLs before initializing your app
37
36
  * bootstrapRuntimeEnv();
38
- *
39
- * // Now createApp() will use the correct env vars
40
- * const app = await createApp();
41
37
  * ```
42
38
  */
43
39
  export declare function bootstrapRuntimeEnv(options?: RuntimeBootstrapOptions): void;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-bootstrap.d.ts","sourceRoot":"","sources":["../src/runtime-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,uBAAuB;IACvC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,uBAA4B,GAAG,IAAI,CA6C/E"}
1
+ {"version":3,"file":"runtime-bootstrap.d.ts","sourceRoot":"","sources":["../src/runtime-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,uBAAuB;IACvC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,uBAA4B,GAAG,IAAI,CA6C/E"}
@@ -16,18 +16,14 @@ import { getServiceUrls } from "./config.js";
16
16
  * Note: This does NOT load .env files. Use a proper .env loader
17
17
  * (like dotenv) in your app.ts before calling this function.
18
18
  *
19
- * Call this BEFORE createApp() in your app.ts:
19
+ * Call this early in your app entry point:
20
20
  *
21
21
  * @example
22
22
  * ```ts
23
23
  * import { bootstrapRuntimeEnv } from '@agentuity/server';
24
- * import { createApp } from '@agentuity/runtime';
25
24
  *
26
- * // Set up service URLs
25
+ * // Set up service URLs before initializing your app
27
26
  * bootstrapRuntimeEnv();
28
- *
29
- * // Now createApp() will use the correct env vars
30
- * const app = await createApp();
31
27
  * ```
32
28
  */
33
29
  export function bootstrapRuntimeEnv(options = {}) {
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-bootstrap.js","sourceRoot":"","sources":["../src/runtime-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAe7C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAmC,EAAE;IACxE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC;IAE5E,6DAA6D;IAC7D,IACC,CAAC,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC;QAC/D,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAC5B,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,OAAO,CAAC;IACxC,CAAC;IAED,kDAAkD;IAClD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,OAAO,CAAC;IACzC,CAAC;IAED,mCAAmC;IACnC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC5C,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAE3C,2EAA2E;IAC3E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,WAAW,CAAC,QAAQ,CAAC;IAC5D,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,sBAAsB,GAAG,WAAW,CAAC,QAAQ,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,qBAAqB,GAAG,WAAW,CAAC,OAAO,CAAC;IACzD,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,WAAW,CAAC,MAAM,CAAC;IACvD,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,WAAW,CAAC,MAAM,CAAC;IACvD,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,sBAAsB,GAAG,WAAW,CAAC,QAAQ,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,WAAW,CAAC,IAAI,CAAC;IACnD,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,WAAW,CAAC,KAAK,CAAC;IACrD,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"runtime-bootstrap.js","sourceRoot":"","sources":["../src/runtime-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAe7C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAmC,EAAE;IACxE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC;IAE5E,6DAA6D;IAC7D,IACC,CAAC,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC;QAC/D,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAC5B,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,OAAO,CAAC;IACxC,CAAC;IAED,kDAAkD;IAClD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,OAAO,CAAC;IACzC,CAAC;IAED,mCAAmC;IACnC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC5C,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAE3C,2EAA2E;IAC3E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,WAAW,CAAC,QAAQ,CAAC;IAC5D,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,sBAAsB,GAAG,WAAW,CAAC,QAAQ,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,qBAAqB,GAAG,WAAW,CAAC,OAAO,CAAC;IACzD,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,WAAW,CAAC,MAAM,CAAC;IACvD,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,WAAW,CAAC,MAAM,CAAC;IACvD,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,sBAAsB,GAAG,WAAW,CAAC,QAAQ,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,WAAW,CAAC,IAAI,CAAC;IACnD,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,WAAW,CAAC,KAAK,CAAC;IACrD,CAAC;AACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentuity/server",
3
- "version": "2.0.10",
3
+ "version": "3.0.0-alpha.0",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Agentuity employees and contributors",
6
6
  "type": "module",
@@ -20,24 +20,30 @@
20
20
  },
21
21
  "scripts": {
22
22
  "clean": "rm -rf dist tsconfig.tsbuildinfo",
23
- "build": "bunx tsc --build --force",
24
- "typecheck": "bunx tsc --noEmit",
23
+ "build": "tsgo --build --force",
24
+ "typecheck": "tsgo --noEmit",
25
25
  "prepublishOnly": "bun run clean && bun run build"
26
26
  },
27
27
  "dependencies": {
28
- "@agentuity/core": "2.0.10",
29
- "@agentuity/schema": "2.0.10",
28
+ "@agentuity/adapter": "3.0.0-alpha.0",
29
+ "@agentuity/core": "3.0.0-alpha.0",
30
+ "@agentuity/schema": "3.0.0-alpha.0",
30
31
  "zod": "^4.3.5"
31
32
  },
32
33
  "devDependencies": {
33
- "@agentuity/test-utils": "2.0.10",
34
+ "@agentuity/test-utils": "3.0.0-alpha.0",
34
35
  "@types/bun": "latest",
35
36
  "@types/node": "^22.0.0",
36
37
  "bun-types": "latest",
37
- "typescript": "^5.9.0"
38
+ "typescript": "^6.0.2"
38
39
  },
39
40
  "publishConfig": {
40
41
  "access": "public"
41
42
  },
42
- "sideEffects": false
43
+ "sideEffects": false,
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "https://github.com/agentuity/sdk.git",
47
+ "directory": "packages/server"
48
+ }
43
49
  }
package/src/index.ts CHANGED
@@ -1,13 +1,19 @@
1
- // Re-export ALL API modules from core (moved there for browser compatibility)
2
- export * from '@agentuity/core';
3
-
4
- // Server-specific exports (these remain in @agentuity/server only)
5
- export { type ColorScheme, ConsoleLogger, createLogger } from './logger.ts';
1
+ // Re-export adapter functions (backward compatibility - prefer @agentuity/adapter)
6
2
  export {
7
3
  createServerFetchAdapter,
8
4
  buildClientHeaders,
9
5
  type BuildClientHeadersOptions,
10
- } from './server.ts';
6
+ type ServiceAdapterConfig,
7
+ redact,
8
+ } from '@agentuity/adapter';
9
+
10
+ // Re-export commonly used types from core
11
+ // Note: Full re-export maintained for backward compatibility with CLI and other packages
12
+ // TODO: Phase 2 - Migrate CLI imports to @agentuity/core directly, then remove this re-export
13
+ export * from '@agentuity/core';
14
+
15
+ // Server-specific exports (these remain in @agentuity/server only)
16
+ export { type ColorScheme, ConsoleLogger, createLogger } from './logger.ts';
11
17
  export { toJSONSchema } from './schema.ts';
12
18
  export { getContentType, mimeTypes } from './util/mime.ts';
13
19
  export {
@@ -31,18 +31,14 @@ export interface RuntimeBootstrapOptions {
31
31
  * Note: This does NOT load .env files. Use a proper .env loader
32
32
  * (like dotenv) in your app.ts before calling this function.
33
33
  *
34
- * Call this BEFORE createApp() in your app.ts:
34
+ * Call this early in your app entry point:
35
35
  *
36
36
  * @example
37
37
  * ```ts
38
38
  * import { bootstrapRuntimeEnv } from '@agentuity/server';
39
- * import { createApp } from '@agentuity/runtime';
40
39
  *
41
- * // Set up service URLs
40
+ * // Set up service URLs before initializing your app
42
41
  * bootstrapRuntimeEnv();
43
- *
44
- * // Now createApp() will use the correct env vars
45
- * const app = await createApp();
46
42
  * ```
47
43
  */
48
44
  export function bootstrapRuntimeEnv(options: RuntimeBootstrapOptions = {}): void {
package/dist/server.d.ts DELETED
@@ -1,60 +0,0 @@
1
- import type { FetchRequest, FetchResponse, FetchAdapter, Logger } from '@agentuity/core';
2
- import { ServiceException } from '@agentuity/core';
3
- interface ServiceAdapterConfig {
4
- headers: Record<string, string>;
5
- queryParams?: Record<string, string>;
6
- onBefore?: (url: string, options: FetchRequest, invoke: () => Promise<void>) => Promise<void>;
7
- onAfter?: <T>(url: string, options: FetchRequest, response: FetchResponse<T>, err?: InstanceType<typeof ServiceException>) => Promise<void>;
8
- }
9
- /**
10
- * Options for building client request headers.
11
- */
12
- export interface BuildClientHeadersOptions {
13
- /** API key for authentication (Bearer token) */
14
- apiKey?: string;
15
- /** Organization ID for multi-tenant requests */
16
- orgId?: string;
17
- }
18
- /**
19
- * Builds standard headers for Agentuity service clients.
20
- *
21
- * This helper creates the header object needed by `createServerFetchAdapter`,
22
- * handling authentication and multi-tenant scoping consistently across all clients.
23
- *
24
- * @param options - Options containing apiKey and/or orgId
25
- * @returns Headers object ready to pass to createServerFetchAdapter
26
- *
27
- * @example
28
- * ```typescript
29
- * import { buildClientHeaders, createServerFetchAdapter } from '@agentuity/server';
30
- *
31
- * const headers = buildClientHeaders({ apiKey: 'sk_xxx', orgId: 'org_xxx' });
32
- * const adapter = createServerFetchAdapter({ headers }, logger);
33
- * ```
34
- */
35
- export declare function buildClientHeaders(options: BuildClientHeadersOptions): Record<string, string>;
36
- /**
37
- * Redacts the middle of a string while keeping a prefix and suffix visible.
38
- * Ensures that if the string is too short, everything is redacted.
39
- *
40
- * @param input The string to redact
41
- * @param prefix Number of chars to keep at the start
42
- * @param suffix Number of chars to keep at the end
43
- * @param mask Character used for redaction
44
- */
45
- export declare function redact(input: string, prefix?: number, suffix?: number, mask?: string): string;
46
- declare class ServerFetchAdapter implements FetchAdapter {
47
- #private;
48
- constructor(config: ServiceAdapterConfig, logger: Logger);
49
- private _invoke;
50
- invoke<T>(url: string, options?: FetchRequest): Promise<FetchResponse<T>>;
51
- }
52
- /**
53
- * Create a Server Side Fetch Adapter to allow the server to add headers and track outgoing requests
54
- *
55
- * @param config the service config
56
- * @returns
57
- */
58
- export declare function createServerFetchAdapter(config: ServiceAdapterConfig, logger: Logger): ServerFetchAdapter;
59
- export {};
60
- //# sourceMappingURL=server.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,YAAY,EAEZ,aAAa,EACb,YAAY,EACZ,MAAM,EAEN,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAoC,MAAM,iBAAiB,CAAC;AAGrF,UAAU,oBAAoB;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9F,OAAO,CAAC,EAAE,CAAC,CAAC,EACX,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,EAC1B,GAAG,CAAC,EAAE,YAAY,CAAC,OAAO,gBAAgB,CAAC,KACvC,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACzC,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAa7F;AAqKD;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CACrB,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,MAAU,EAClB,MAAM,GAAE,MAAU,EAClB,IAAI,GAAE,MAAY,GAChB,MAAM,CAaR;AAmBD,cAAM,kBAAmB,YAAW,YAAY;;gBAInC,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM;YAoB1C,OAAO;IA0Ef,MAAM,CAAC,CAAC,EACb,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,YAAiC,GACxC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;CAsC5B;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,sBAEpF"}
package/dist/server.js DELETED
@@ -1,360 +0,0 @@
1
- import { ServiceException, toServiceException, fromResponse } from '@agentuity/core';
2
- import { appendFileSync } from 'node:fs';
3
- /**
4
- * Builds standard headers for Agentuity service clients.
5
- *
6
- * This helper creates the header object needed by `createServerFetchAdapter`,
7
- * handling authentication and multi-tenant scoping consistently across all clients.
8
- *
9
- * @param options - Options containing apiKey and/or orgId
10
- * @returns Headers object ready to pass to createServerFetchAdapter
11
- *
12
- * @example
13
- * ```typescript
14
- * import { buildClientHeaders, createServerFetchAdapter } from '@agentuity/server';
15
- *
16
- * const headers = buildClientHeaders({ apiKey: 'sk_xxx', orgId: 'org_xxx' });
17
- * const adapter = createServerFetchAdapter({ headers }, logger);
18
- * ```
19
- */
20
- export function buildClientHeaders(options) {
21
- const headers = options.apiKey
22
- ? {
23
- Authorization: `Bearer ${options.apiKey}`,
24
- 'Content-Type': 'application/json',
25
- }
26
- : { 'Content-Type': 'application/json' };
27
- if (options.orgId) {
28
- headers['x-agentuity-orgid'] = options.orgId;
29
- }
30
- return headers;
31
- }
32
- /**
33
- * Headers that contain sensitive information and should be redacted in debug logs.
34
- * Includes authentication tokens, API keys, cookies, and proxy credentials.
35
- */
36
- const sensitiveHeaders = new Set([
37
- 'authorization',
38
- 'x-api-key',
39
- 'cookie',
40
- 'set-cookie',
41
- 'proxy-authorization',
42
- ]);
43
- /**
44
- * Check if API debug logging is enabled and return the output destination.
45
- * Returns:
46
- * - 'console' if CI=1/true or AGENTUITY_API_DEBUG=1/true
47
- * - file path string if AGENTUITY_API_DEBUG is set to a path
48
- * - null if debug logging is disabled (including AGENTUITY_API_DEBUG=0/false)
49
- */
50
- function getDebugOutput() {
51
- const apiDebug = process.env.AGENTUITY_API_DEBUG?.trim();
52
- if (apiDebug) {
53
- const normalized = apiDebug.toLowerCase();
54
- // Check if explicitly disabled
55
- if (normalized === '0' || normalized === 'false') {
56
- return null;
57
- }
58
- // Check if it's a truthy value (console output)
59
- if (normalized === '1' || normalized === 'true') {
60
- return 'console';
61
- }
62
- // Treat any other non-empty value as a file path
63
- return apiDebug;
64
- }
65
- // Fall back to CI environment check
66
- if (process.env.CI === '1' || process.env.CI === 'true') {
67
- return 'console';
68
- }
69
- return null;
70
- }
71
- /**
72
- * Format request body for CI debug logging
73
- */
74
- function formatRequestBody(body) {
75
- if (body === undefined || body === null) {
76
- return '[no body]';
77
- }
78
- if (typeof body === 'string') {
79
- return body;
80
- }
81
- if (body instanceof Uint8Array) {
82
- return `[binary data: ${body.length} bytes]`;
83
- }
84
- if (body instanceof ArrayBuffer) {
85
- return `[binary data: ${body.byteLength} bytes]`;
86
- }
87
- if (body instanceof ReadableStream) {
88
- return '[stream]';
89
- }
90
- return String(body);
91
- }
92
- /**
93
- * Format a sensitive header value, preserving Bearer prefix if present.
94
- */
95
- function redactSensitiveHeader(key, value) {
96
- const _k = key.toLowerCase();
97
- // Handle Bearer tokens in authorization and proxy-authorization headers
98
- if ((_k === 'authorization' || _k === 'proxy-authorization') && value.startsWith('Bearer ')) {
99
- return `Bearer ${redact(value.substring(7))}`;
100
- }
101
- return redact(value);
102
- }
103
- /**
104
- * Format headers as a readable string for debug logging.
105
- * Sensitive headers (auth tokens, cookies, API keys) are redacted.
106
- */
107
- function formatHeaders(headers) {
108
- const entries = [];
109
- if (headers instanceof Headers) {
110
- headers.forEach((value, key) => {
111
- const _k = key.toLowerCase();
112
- if (sensitiveHeaders.has(_k)) {
113
- entries.push(` ${key}: ${redactSensitiveHeader(key, value)}`);
114
- }
115
- else {
116
- entries.push(` ${key}: ${value}`);
117
- }
118
- });
119
- }
120
- else {
121
- for (const [key, value] of Object.entries(headers)) {
122
- const _k = key.toLowerCase();
123
- if (sensitiveHeaders.has(_k)) {
124
- entries.push(` ${key}: ${redactSensitiveHeader(key, value)}`);
125
- }
126
- else {
127
- entries.push(` ${key}: ${value}`);
128
- }
129
- }
130
- }
131
- return entries.join('\n');
132
- }
133
- /**
134
- * Log detailed debug information when API requests fail.
135
- * Output destination is determined by AGENTUITY_API_DEBUG or CI environment variables.
136
- */
137
- function logAPIDebug(url, method, requestHeaders, requestBody, response, responseBody) {
138
- const output = getDebugOutput();
139
- if (!output) {
140
- return;
141
- }
142
- const separator = '='.repeat(60);
143
- const timestamp = new Date().toISOString();
144
- const lines = [
145
- '',
146
- separator,
147
- `API DEBUG: Request Failed [${timestamp}]`,
148
- separator,
149
- '',
150
- '>>> REQUEST',
151
- `URL: ${url}`,
152
- `Method: ${method}`,
153
- 'Headers:',
154
- formatHeaders(requestHeaders),
155
- 'Body:',
156
- ` ${formatRequestBody(requestBody)}`,
157
- '',
158
- '<<< RESPONSE',
159
- `Status: ${response.status} ${response.statusText}`,
160
- 'Headers:',
161
- formatHeaders(response.headers),
162
- 'Body:',
163
- ` ${responseBody || '[empty]'}`,
164
- '',
165
- separator,
166
- '',
167
- ];
168
- const content = lines.join('\n');
169
- if (output === 'console') {
170
- console.error(content);
171
- }
172
- else {
173
- // Append to file
174
- try {
175
- appendFileSync(output, content + '\n');
176
- }
177
- catch {
178
- // If file write fails, fall back to console.error
179
- console.error(`[API DEBUG] Failed to write to ${output}, falling back to console`);
180
- console.error(content);
181
- }
182
- }
183
- }
184
- /**
185
- * Redacts the middle of a string while keeping a prefix and suffix visible.
186
- * Ensures that if the string is too short, everything is redacted.
187
- *
188
- * @param input The string to redact
189
- * @param prefix Number of chars to keep at the start
190
- * @param suffix Number of chars to keep at the end
191
- * @param mask Character used for redaction
192
- */
193
- export function redact(input, prefix = 4, suffix = 4, mask = '*') {
194
- if (!input)
195
- return '';
196
- // If revealing prefix+suffix would leak too much, fully mask
197
- if (input.length <= prefix + suffix) {
198
- return mask.repeat(input.length);
199
- }
200
- const start = input.slice(0, prefix);
201
- const end = input.slice(-suffix);
202
- const hiddenLength = input.length - prefix - suffix;
203
- return start + mask.repeat(hiddenLength) + end;
204
- }
205
- const redactHeaders = (kv) => {
206
- const values = [];
207
- for (const k of Object.keys(kv)) {
208
- const _k = k.toLowerCase();
209
- const v = kv[k];
210
- if (v === undefined) {
211
- continue;
212
- }
213
- if (sensitiveHeaders.has(_k)) {
214
- values.push(`${_k}=${redactSensitiveHeader(k, v)}`);
215
- }
216
- else {
217
- values.push(`${_k}=${v}`);
218
- }
219
- }
220
- return '[' + values.join(',') + ']';
221
- };
222
- class ServerFetchAdapter {
223
- #config;
224
- #logger;
225
- constructor(config, logger) {
226
- this.#config = config;
227
- this.#logger = logger;
228
- }
229
- /**
230
- * Build the final URL with query params appended.
231
- * This is extracted so both invoke() and _invoke() use the same URL.
232
- */
233
- #buildUrl(url) {
234
- if (this.#config.queryParams && Object.keys(this.#config.queryParams).length > 0) {
235
- const urlObj = new URL(url);
236
- for (const [key, value] of Object.entries(this.#config.queryParams)) {
237
- urlObj.searchParams.set(key, value);
238
- }
239
- return urlObj.toString();
240
- }
241
- return url;
242
- }
243
- async _invoke(url, options) {
244
- // URL already has query params appended by invoke() or direct caller
245
- const headers = {
246
- ...options.headers,
247
- ...this.#config.headers,
248
- };
249
- if (options.contentType) {
250
- headers['Content-Type'] = options.contentType;
251
- }
252
- else if (typeof options.body === 'string' ||
253
- options.body instanceof Uint8Array ||
254
- options.body instanceof ArrayBuffer) {
255
- headers['Content-Type'] = 'application/octet-stream';
256
- }
257
- // Ensure we request JSON responses for proper error handling
258
- if (!headers['Accept'] && !headers['accept']) {
259
- headers['Accept'] = 'application/json';
260
- }
261
- const method = options.method ?? 'POST';
262
- this.#logger.trace('sending %s to %s with headers: %s', method, url, redactHeaders(headers));
263
- const res = await fetch(url, {
264
- method,
265
- body: options.body,
266
- headers,
267
- signal: options.signal,
268
- ...(options.duplex ? { duplex: options.duplex } : {}),
269
- });
270
- if (res.ok) {
271
- switch (res.status) {
272
- case 100:
273
- case 101:
274
- case 102:
275
- case 204:
276
- case 304:
277
- return {
278
- ok: true,
279
- data: undefined,
280
- response: res,
281
- };
282
- default:
283
- break;
284
- }
285
- if (options?.binary) {
286
- return {
287
- ok: true,
288
- data: undefined,
289
- response: res,
290
- };
291
- }
292
- const data = await fromResponse(res);
293
- return {
294
- ok: true,
295
- data,
296
- response: res,
297
- };
298
- }
299
- if (res.status === 404) {
300
- // Log debug info for 404 errors if debugging is enabled
301
- if (getDebugOutput()) {
302
- const responseBody = await res.clone().text();
303
- logAPIDebug(url, method, headers, options.body, res, responseBody);
304
- }
305
- return {
306
- ok: false,
307
- response: res,
308
- };
309
- }
310
- // Clone response to read body for debug logging before toServiceException consumes it
311
- const responseBody = getDebugOutput() ? await res.clone().text() : '';
312
- logAPIDebug(url, method, headers, options.body, res, responseBody);
313
- const err = await toServiceException(method, url, res);
314
- throw err;
315
- }
316
- async invoke(url, options = { method: 'POST' }) {
317
- // Build final URL with query params BEFORE hooks, so hooks receive the actual URL
318
- const finalUrl = this.#buildUrl(url);
319
- if (this.#config.onBefore) {
320
- let result = undefined;
321
- let err = undefined;
322
- await this.#config.onBefore(finalUrl, options, async () => {
323
- try {
324
- result = await this._invoke(finalUrl, options);
325
- if (this.#config.onAfter) {
326
- await this.#config.onAfter(finalUrl, options, result);
327
- }
328
- }
329
- catch (ex) {
330
- err = ex;
331
- if (this.#config.onAfter && err instanceof ServiceException) {
332
- await this.#config.onAfter(finalUrl, options, {
333
- ok: false,
334
- response: new Response(err.message, {
335
- status: err.statusCode,
336
- }),
337
- }, err);
338
- }
339
- }
340
- });
341
- if (err) {
342
- throw err;
343
- }
344
- return result;
345
- }
346
- else {
347
- return await this._invoke(finalUrl, options);
348
- }
349
- }
350
- }
351
- /**
352
- * Create a Server Side Fetch Adapter to allow the server to add headers and track outgoing requests
353
- *
354
- * @param config the service config
355
- * @returns
356
- */
357
- export function createServerFetchAdapter(config, logger) {
358
- return new ServerFetchAdapter(config, logger);
359
- }
360
- //# sourceMappingURL=server.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/src/server.ts DELETED
@@ -1,424 +0,0 @@
1
- import type {
2
- FetchRequest,
3
- FetchErrorResponse,
4
- FetchResponse,
5
- FetchAdapter,
6
- Logger,
7
- HttpMethod,
8
- } from '@agentuity/core';
9
- import { ServiceException, toServiceException, fromResponse } from '@agentuity/core';
10
- import { appendFileSync } from 'node:fs';
11
-
12
- interface ServiceAdapterConfig {
13
- headers: Record<string, string>;
14
- queryParams?: Record<string, string>;
15
- onBefore?: (url: string, options: FetchRequest, invoke: () => Promise<void>) => Promise<void>;
16
- onAfter?: <T>(
17
- url: string,
18
- options: FetchRequest,
19
- response: FetchResponse<T>,
20
- err?: InstanceType<typeof ServiceException>
21
- ) => Promise<void>;
22
- }
23
-
24
- /**
25
- * Options for building client request headers.
26
- */
27
- export interface BuildClientHeadersOptions {
28
- /** API key for authentication (Bearer token) */
29
- apiKey?: string;
30
- /** Organization ID for multi-tenant requests */
31
- orgId?: string;
32
- }
33
-
34
- /**
35
- * Builds standard headers for Agentuity service clients.
36
- *
37
- * This helper creates the header object needed by `createServerFetchAdapter`,
38
- * handling authentication and multi-tenant scoping consistently across all clients.
39
- *
40
- * @param options - Options containing apiKey and/or orgId
41
- * @returns Headers object ready to pass to createServerFetchAdapter
42
- *
43
- * @example
44
- * ```typescript
45
- * import { buildClientHeaders, createServerFetchAdapter } from '@agentuity/server';
46
- *
47
- * const headers = buildClientHeaders({ apiKey: 'sk_xxx', orgId: 'org_xxx' });
48
- * const adapter = createServerFetchAdapter({ headers }, logger);
49
- * ```
50
- */
51
- export function buildClientHeaders(options: BuildClientHeadersOptions): Record<string, string> {
52
- const headers: Record<string, string> = options.apiKey
53
- ? {
54
- Authorization: `Bearer ${options.apiKey}`,
55
- 'Content-Type': 'application/json',
56
- }
57
- : { 'Content-Type': 'application/json' };
58
-
59
- if (options.orgId) {
60
- headers['x-agentuity-orgid'] = options.orgId;
61
- }
62
-
63
- return headers;
64
- }
65
-
66
- /**
67
- * Headers that contain sensitive information and should be redacted in debug logs.
68
- * Includes authentication tokens, API keys, cookies, and proxy credentials.
69
- */
70
- const sensitiveHeaders = new Set([
71
- 'authorization',
72
- 'x-api-key',
73
- 'cookie',
74
- 'set-cookie',
75
- 'proxy-authorization',
76
- ]);
77
-
78
- /**
79
- * Check if API debug logging is enabled and return the output destination.
80
- * Returns:
81
- * - 'console' if CI=1/true or AGENTUITY_API_DEBUG=1/true
82
- * - file path string if AGENTUITY_API_DEBUG is set to a path
83
- * - null if debug logging is disabled (including AGENTUITY_API_DEBUG=0/false)
84
- */
85
- function getDebugOutput(): 'console' | string | null {
86
- const apiDebug = process.env.AGENTUITY_API_DEBUG?.trim();
87
- if (apiDebug) {
88
- const normalized = apiDebug.toLowerCase();
89
- // Check if explicitly disabled
90
- if (normalized === '0' || normalized === 'false') {
91
- return null;
92
- }
93
- // Check if it's a truthy value (console output)
94
- if (normalized === '1' || normalized === 'true') {
95
- return 'console';
96
- }
97
- // Treat any other non-empty value as a file path
98
- return apiDebug;
99
- }
100
- // Fall back to CI environment check
101
- if (process.env.CI === '1' || process.env.CI === 'true') {
102
- return 'console';
103
- }
104
- return null;
105
- }
106
-
107
- /**
108
- * Format request body for CI debug logging
109
- */
110
- function formatRequestBody(body: unknown): string {
111
- if (body === undefined || body === null) {
112
- return '[no body]';
113
- }
114
- if (typeof body === 'string') {
115
- return body;
116
- }
117
- if (body instanceof Uint8Array) {
118
- return `[binary data: ${body.length} bytes]`;
119
- }
120
- if (body instanceof ArrayBuffer) {
121
- return `[binary data: ${body.byteLength} bytes]`;
122
- }
123
- if (body instanceof ReadableStream) {
124
- return '[stream]';
125
- }
126
- return String(body);
127
- }
128
-
129
- /**
130
- * Format a sensitive header value, preserving Bearer prefix if present.
131
- */
132
- function redactSensitiveHeader(key: string, value: string): string {
133
- const _k = key.toLowerCase();
134
- // Handle Bearer tokens in authorization and proxy-authorization headers
135
- if ((_k === 'authorization' || _k === 'proxy-authorization') && value.startsWith('Bearer ')) {
136
- return `Bearer ${redact(value.substring(7))}`;
137
- }
138
- return redact(value);
139
- }
140
-
141
- /**
142
- * Format headers as a readable string for debug logging.
143
- * Sensitive headers (auth tokens, cookies, API keys) are redacted.
144
- */
145
- function formatHeaders(headers: Headers | Record<string, string>): string {
146
- const entries: string[] = [];
147
- if (headers instanceof Headers) {
148
- headers.forEach((value, key) => {
149
- const _k = key.toLowerCase();
150
- if (sensitiveHeaders.has(_k)) {
151
- entries.push(` ${key}: ${redactSensitiveHeader(key, value)}`);
152
- } else {
153
- entries.push(` ${key}: ${value}`);
154
- }
155
- });
156
- } else {
157
- for (const [key, value] of Object.entries(headers)) {
158
- const _k = key.toLowerCase();
159
- if (sensitiveHeaders.has(_k)) {
160
- entries.push(` ${key}: ${redactSensitiveHeader(key, value)}`);
161
- } else {
162
- entries.push(` ${key}: ${value}`);
163
- }
164
- }
165
- }
166
- return entries.join('\n');
167
- }
168
-
169
- /**
170
- * Log detailed debug information when API requests fail.
171
- * Output destination is determined by AGENTUITY_API_DEBUG or CI environment variables.
172
- */
173
- function logAPIDebug(
174
- url: string,
175
- method: string,
176
- requestHeaders: Record<string, string>,
177
- requestBody: unknown,
178
- response: Response,
179
- responseBody: string
180
- ): void {
181
- const output = getDebugOutput();
182
- if (!output) {
183
- return;
184
- }
185
-
186
- const separator = '='.repeat(60);
187
- const timestamp = new Date().toISOString();
188
- const lines = [
189
- '',
190
- separator,
191
- `API DEBUG: Request Failed [${timestamp}]`,
192
- separator,
193
- '',
194
- '>>> REQUEST',
195
- `URL: ${url}`,
196
- `Method: ${method}`,
197
- 'Headers:',
198
- formatHeaders(requestHeaders),
199
- 'Body:',
200
- ` ${formatRequestBody(requestBody)}`,
201
- '',
202
- '<<< RESPONSE',
203
- `Status: ${response.status} ${response.statusText}`,
204
- 'Headers:',
205
- formatHeaders(response.headers),
206
- 'Body:',
207
- ` ${responseBody || '[empty]'}`,
208
- '',
209
- separator,
210
- '',
211
- ];
212
-
213
- const content = lines.join('\n');
214
-
215
- if (output === 'console') {
216
- console.error(content);
217
- } else {
218
- // Append to file
219
- try {
220
- appendFileSync(output, content + '\n');
221
- } catch {
222
- // If file write fails, fall back to console.error
223
- console.error(`[API DEBUG] Failed to write to ${output}, falling back to console`);
224
- console.error(content);
225
- }
226
- }
227
- }
228
-
229
- /**
230
- * Redacts the middle of a string while keeping a prefix and suffix visible.
231
- * Ensures that if the string is too short, everything is redacted.
232
- *
233
- * @param input The string to redact
234
- * @param prefix Number of chars to keep at the start
235
- * @param suffix Number of chars to keep at the end
236
- * @param mask Character used for redaction
237
- */
238
- export function redact(
239
- input: string,
240
- prefix: number = 4,
241
- suffix: number = 4,
242
- mask: string = '*'
243
- ): string {
244
- if (!input) return '';
245
-
246
- // If revealing prefix+suffix would leak too much, fully mask
247
- if (input.length <= prefix + suffix) {
248
- return mask.repeat(input.length);
249
- }
250
-
251
- const start = input.slice(0, prefix);
252
- const end = input.slice(-suffix);
253
- const hiddenLength = input.length - prefix - suffix;
254
-
255
- return start + mask.repeat(hiddenLength) + end;
256
- }
257
-
258
- const redactHeaders = (kv: Record<string, string>): string => {
259
- const values: string[] = [];
260
- for (const k of Object.keys(kv)) {
261
- const _k = k.toLowerCase();
262
- const v = kv[k];
263
- if (v === undefined) {
264
- continue;
265
- }
266
- if (sensitiveHeaders.has(_k)) {
267
- values.push(`${_k}=${redactSensitiveHeader(k, v)}`);
268
- } else {
269
- values.push(`${_k}=${v}`);
270
- }
271
- }
272
- return '[' + values.join(',') + ']';
273
- };
274
-
275
- class ServerFetchAdapter implements FetchAdapter {
276
- #config: ServiceAdapterConfig;
277
- #logger: Logger;
278
-
279
- constructor(config: ServiceAdapterConfig, logger: Logger) {
280
- this.#config = config;
281
- this.#logger = logger;
282
- }
283
-
284
- /**
285
- * Build the final URL with query params appended.
286
- * This is extracted so both invoke() and _invoke() use the same URL.
287
- */
288
- #buildUrl(url: string): string {
289
- if (this.#config.queryParams && Object.keys(this.#config.queryParams).length > 0) {
290
- const urlObj = new URL(url);
291
- for (const [key, value] of Object.entries(this.#config.queryParams)) {
292
- urlObj.searchParams.set(key, value);
293
- }
294
- return urlObj.toString();
295
- }
296
- return url;
297
- }
298
-
299
- private async _invoke<T>(url: string, options: FetchRequest): Promise<FetchResponse<T>> {
300
- // URL already has query params appended by invoke() or direct caller
301
- const headers: Record<string, string> = {
302
- ...options.headers,
303
- ...this.#config.headers,
304
- };
305
- if (options.contentType) {
306
- headers['Content-Type'] = options.contentType;
307
- } else if (
308
- typeof options.body === 'string' ||
309
- options.body instanceof Uint8Array ||
310
- options.body instanceof ArrayBuffer
311
- ) {
312
- headers['Content-Type'] = 'application/octet-stream';
313
- }
314
- // Ensure we request JSON responses for proper error handling
315
- if (!headers['Accept'] && !headers['accept']) {
316
- headers['Accept'] = 'application/json';
317
- }
318
- const method: HttpMethod = options.method ?? 'POST';
319
- this.#logger.trace('sending %s to %s with headers: %s', method, url, redactHeaders(headers));
320
- const res = await fetch(url, {
321
- method,
322
- body: options.body,
323
- headers,
324
- signal: options.signal,
325
- ...(options.duplex ? { duplex: options.duplex } : {}),
326
- });
327
- if (res.ok) {
328
- switch (res.status) {
329
- case 100:
330
- case 101:
331
- case 102:
332
- case 204:
333
- case 304:
334
- return {
335
- ok: true,
336
- data: undefined as T,
337
- response: res,
338
- };
339
- default:
340
- break;
341
- }
342
- if (options?.binary) {
343
- return {
344
- ok: true,
345
- data: undefined as T,
346
- response: res,
347
- };
348
- }
349
- const data = await fromResponse<T>(res);
350
- return {
351
- ok: true,
352
- data,
353
- response: res,
354
- };
355
- }
356
- if (res.status === 404) {
357
- // Log debug info for 404 errors if debugging is enabled
358
- if (getDebugOutput()) {
359
- const responseBody = await res.clone().text();
360
- logAPIDebug(url, method, headers, options.body, res, responseBody);
361
- }
362
- return {
363
- ok: false,
364
- response: res,
365
- } as FetchErrorResponse;
366
- }
367
- // Clone response to read body for debug logging before toServiceException consumes it
368
- const responseBody = getDebugOutput() ? await res.clone().text() : '';
369
- logAPIDebug(url, method, headers, options.body, res, responseBody);
370
- const err = await toServiceException(method, url, res);
371
- throw err;
372
- }
373
- async invoke<T>(
374
- url: string,
375
- options: FetchRequest = { method: 'POST' }
376
- ): Promise<FetchResponse<T>> {
377
- // Build final URL with query params BEFORE hooks, so hooks receive the actual URL
378
- const finalUrl = this.#buildUrl(url);
379
-
380
- if (this.#config.onBefore) {
381
- let result: FetchResponse<T> | undefined = undefined;
382
- let err: Error | undefined = undefined;
383
- await this.#config.onBefore(finalUrl, options, async () => {
384
- try {
385
- result = await this._invoke(finalUrl, options);
386
- if (this.#config.onAfter) {
387
- await this.#config.onAfter(finalUrl, options, result);
388
- }
389
- } catch (ex) {
390
- err = ex as Error;
391
- if (this.#config.onAfter && err instanceof ServiceException) {
392
- await this.#config.onAfter(
393
- finalUrl,
394
- options,
395
- {
396
- ok: false,
397
- response: new Response(err.message, {
398
- status: err.statusCode,
399
- }),
400
- } as FetchErrorResponse,
401
- err
402
- );
403
- }
404
- }
405
- });
406
- if (err) {
407
- throw err;
408
- }
409
- return result as unknown as FetchResponse<T>;
410
- } else {
411
- return await this._invoke(finalUrl, options);
412
- }
413
- }
414
- }
415
-
416
- /**
417
- * Create a Server Side Fetch Adapter to allow the server to add headers and track outgoing requests
418
- *
419
- * @param config the service config
420
- * @returns
421
- */
422
- export function createServerFetchAdapter(config: ServiceAdapterConfig, logger: Logger) {
423
- return new ServerFetchAdapter(config, logger);
424
- }