@bernierllc/admin-agent-nextjs 0.0.1 → 0.1.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/README.md CHANGED
@@ -1,45 +1,83 @@
1
1
  # @bernierllc/admin-agent-nextjs
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
3
+ Thin Next.js App Router adapter that wraps an `AdminAgent` into a streaming SSE POST route handler with auth, validation, and error mapping.
4
4
 
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
5
+ ## Installation
6
6
 
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
7
+ ```bash
8
+ npm install @bernierllc/admin-agent-nextjs @bernierllc/admin-agent-service
9
+ ```
8
10
 
9
- ## Purpose
11
+ Peer dependency: `next >= 14.0.0 < 16`.
10
12
 
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@bernierllc/admin-agent-nextjs`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
13
+ ## Usage
15
14
 
16
- ## What is OIDC Trusted Publishing?
15
+ ```typescript
16
+ // app/api/chat/admin/route.ts
17
+ import { createAdminAgentRouteHandler } from '@bernierllc/admin-agent-nextjs';
18
+ import { adminAgent } from '@/lib/admin-agent';
19
+ import { getServerSession } from 'next-auth';
20
+ import { AdminAgentRouteUnauthorizedError } from '@bernierllc/admin-agent-nextjs';
17
21
 
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
22
+ export const POST = createAdminAgentRouteHandler({
23
+ agent: adminAgent,
19
24
 
20
- ## Setup Instructions
25
+ auth: async (request) => {
26
+ const session = await getServerSession();
27
+ if (!session?.user) {
28
+ throw new AdminAgentRouteUnauthorizedError('Not authenticated');
29
+ }
30
+ return { userId: session.user.id, orgId: session.user.orgId };
31
+ },
32
+ });
33
+ ```
21
34
 
22
- To properly configure OIDC trusted publishing for this package:
35
+ ## API
23
36
 
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
37
+ ### `createAdminAgentRouteHandler(config)`
28
38
 
29
- ## DO NOT USE THIS PACKAGE
39
+ Returns an `async (request: Request) => Promise<Response>` function suitable for `export const POST` in a Next.js App Router route file.
30
40
 
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
41
+ **Config options:**
36
42
 
37
- ## More Information
43
+ | Field | Type | Description |
44
+ |---|---|---|
45
+ | `agent` | `AdminAgent` | Agent instance from `@bernierllc/admin-agent-service` |
46
+ | `auth` | `(request: Request) => Promise<AuthContext>` | Extract auth context; throw `AdminAgentRouteUnauthorizedError` for 401 |
47
+ | `validateBody?` | `(body: unknown) => { message: string }` | Custom body validator; default validates `{ message: string }` |
48
+ | `transformEvent?` | `(event: AdminAgentEvent) => AdminAgentEvent \| null` | Filter or transform events; return `null` to suppress |
38
49
 
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
50
+ ### Errors
42
51
 
43
- ---
52
+ - `AdminAgentRouteError` — base error class
53
+ - `AdminAgentRouteUnauthorizedError` — throw from `auth()` to produce a 401
54
+ - `AdminAgentRouteBodyError` — throw from `validateBody()` to produce a 400
44
55
 
45
- **Maintained for OIDC setup purposes only**
56
+ ### Error-to-HTTP Mapping
57
+
58
+ | Condition | HTTP Status |
59
+ |---|---|
60
+ | Body parse failure | 400 |
61
+ | `validateBody` throws | 400 |
62
+ | `auth` throws `AdminAgentRouteUnauthorizedError` | 401 |
63
+ | `auth` throws any other error | 500 |
64
+ | Agent initialization failure | 500 |
65
+ | `rate-limited` event received | 200 (stream closes with event) |
66
+ | `feature-disabled` event received | 200 (stream closes with event) |
67
+
68
+ ### Response Format
69
+
70
+ Streaming `text/plain; charset=utf-8` with `Transfer-Encoding: chunked`. Events are newline-delimited JSON:
71
+
72
+ ```
73
+ {"type":"text-delta","delta":"Hello"}
74
+ {"type":"done"}
75
+ ```
76
+
77
+ ## Node.js Only
78
+
79
+ This package requires a Node.js server runtime. It is not browser-safe.
80
+
81
+ ## License
82
+
83
+ Copyright (c) 2025 Bernier LLC. All rights reserved.
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Base error for all admin-agent-nextjs exceptional conditions.
3
+ *
4
+ * Uses ES2022 `Error.cause` chaining per the BernierLLC error propagation
5
+ * standard — underlying errors are never swallowed.
6
+ */
7
+ export declare class AdminAgentRouteError extends Error {
8
+ readonly code: string;
9
+ constructor(message: string, options?: {
10
+ cause?: Error;
11
+ code?: string;
12
+ });
13
+ }
14
+ /**
15
+ * Thrown (or to be thrown) from the auth function to produce a 401 response.
16
+ * Consumers throw this from their `auth` callback to signal that the request
17
+ * is not authenticated.
18
+ */
19
+ export declare class AdminAgentRouteUnauthorizedError extends AdminAgentRouteError {
20
+ constructor(message?: string);
21
+ }
22
+ /**
23
+ * Thrown internally when the request body fails validation.
24
+ * Results in a 400 response.
25
+ */
26
+ export declare class AdminAgentRouteBodyError extends AdminAgentRouteError {
27
+ constructor(detail: string);
28
+ }
29
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAGpB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,KAAK,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;CAOJ;AAED;;;;GAIG;AACH,qBAAa,gCAAiC,SAAQ,oBAAoB;gBAC5D,OAAO,SAAiB;CAKrC;AAED;;;GAGG;AACH,qBAAa,wBAAyB,SAAQ,oBAAoB;gBACpD,MAAM,EAAE,MAAM;CAK3B"}
package/dist/errors.js ADDED
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.AdminAgentRouteBodyError = exports.AdminAgentRouteUnauthorizedError = exports.AdminAgentRouteError = void 0;
11
+ /**
12
+ * Base error for all admin-agent-nextjs exceptional conditions.
13
+ *
14
+ * Uses ES2022 `Error.cause` chaining per the BernierLLC error propagation
15
+ * standard — underlying errors are never swallowed.
16
+ */
17
+ class AdminAgentRouteError extends Error {
18
+ code;
19
+ constructor(message, options) {
20
+ super(message, { ...(options?.cause !== undefined ? { cause: options.cause } : {}) });
21
+ this.name = 'AdminAgentRouteError';
22
+ this.code = options?.code ?? 'ROUTE_ERROR';
23
+ Error.captureStackTrace?.(this, this.constructor);
24
+ }
25
+ }
26
+ exports.AdminAgentRouteError = AdminAgentRouteError;
27
+ /**
28
+ * Thrown (or to be thrown) from the auth function to produce a 401 response.
29
+ * Consumers throw this from their `auth` callback to signal that the request
30
+ * is not authenticated.
31
+ */
32
+ class AdminAgentRouteUnauthorizedError extends AdminAgentRouteError {
33
+ constructor(message = 'Unauthorized') {
34
+ super(message, { code: 'UNAUTHORIZED' });
35
+ this.name = 'AdminAgentRouteUnauthorizedError';
36
+ Error.captureStackTrace?.(this, this.constructor);
37
+ }
38
+ }
39
+ exports.AdminAgentRouteUnauthorizedError = AdminAgentRouteUnauthorizedError;
40
+ /**
41
+ * Thrown internally when the request body fails validation.
42
+ * Results in a 400 response.
43
+ */
44
+ class AdminAgentRouteBodyError extends AdminAgentRouteError {
45
+ constructor(detail) {
46
+ super(`Invalid request body: ${detail}`, { code: 'INVALID_BODY' });
47
+ this.name = 'AdminAgentRouteBodyError';
48
+ Error.captureStackTrace?.(this, this.constructor);
49
+ }
50
+ }
51
+ exports.AdminAgentRouteBodyError = AdminAgentRouteBodyError;
52
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;;EAME;;;AAEF;;;;;GAKG;AACH,MAAa,oBAAqB,SAAQ,KAAK;IACpC,IAAI,CAAS;IAEtB,YACE,OAAe,EACf,OAGC;QAED,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACtF,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,aAAa,CAAC;QAC3C,KAAK,CAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACpD,CAAC;CACF;AAfD,oDAeC;AAED;;;;GAIG;AACH,MAAa,gCAAiC,SAAQ,oBAAoB;IACxE,YAAY,OAAO,GAAG,cAAc;QAClC,KAAK,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,kCAAkC,CAAC;QAC/C,KAAK,CAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACpD,CAAC;CACF;AAND,4EAMC;AAED;;;GAGG;AACH,MAAa,wBAAyB,SAAQ,oBAAoB;IAChE,YAAY,MAAc;QACxB,KAAK,CAAC,yBAAyB,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;QACvC,KAAK,CAAC,iBAAiB,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACpD,CAAC;CACF;AAND,4DAMC"}
@@ -0,0 +1,49 @@
1
+ import type { AdminAgent, AuthContext, AdminAgentEvent } from '@bernierllc/admin-agent-service';
2
+ /**
3
+ * Configuration object for the admin-agent route handler factory.
4
+ */
5
+ export interface AdminAgentRouteConfig {
6
+ /**
7
+ * The AdminAgent instance to delegate chat turns to.
8
+ * Obtained via `createAdminAgent()` from `@bernierllc/admin-agent-service`.
9
+ */
10
+ agent: AdminAgent;
11
+ /**
12
+ * Extract and validate auth context from the incoming request.
13
+ * Throw `AdminAgentRouteUnauthorizedError` to return a 401.
14
+ * Throw any other error to return a 500.
15
+ */
16
+ auth(request: Request): Promise<AuthContext>;
17
+ /**
18
+ * Optional body validator. Receives the parsed JSON body and must return
19
+ * `{ message: string }` or throw `AdminAgentRouteBodyError` for a 400.
20
+ * Defaults to a simple `{ message: string }` shape check.
21
+ */
22
+ validateBody?: (body: unknown) => {
23
+ message: string;
24
+ };
25
+ /**
26
+ * Optional event transformer. Called for every `AdminAgentEvent` before it
27
+ * is written to the stream. Return `null` to suppress the event.
28
+ */
29
+ transformEvent?: (event: AdminAgentEvent) => AdminAgentEvent | null;
30
+ }
31
+ /**
32
+ * Creates a Next.js App Router-compatible POST handler that streams
33
+ * `AdminAgentEvent` objects as newline-delimited JSON.
34
+ *
35
+ * Assign directly to `export const POST` in your route file:
36
+ *
37
+ * ```typescript
38
+ * // app/api/chat/admin/route.ts
39
+ * export const POST = createAdminAgentRouteHandler({
40
+ * agent: adminAgent,
41
+ * auth: async (req) => getAuthContextFromRequest(req),
42
+ * });
43
+ * ```
44
+ *
45
+ * @param config - Route configuration including agent, auth, and optional hooks.
46
+ * @returns An async function `(request: Request) => Promise<Response>`.
47
+ */
48
+ export declare function createAdminAgentRouteHandler(config: AdminAgentRouteConfig): (request: Request) => Promise<Response>;
49
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAkBhG;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,KAAK,EAAE,UAAU,CAAC;IAElB;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAE7C;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAEtD;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,eAAe,GAAG,IAAI,CAAC;CACrE;AAgCD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,qBAAqB,GAC5B,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CA8GzC"}
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.createAdminAgentRouteHandler = createAdminAgentRouteHandler;
11
+ const logger_1 = require("@bernierllc/logger");
12
+ const errors_1 = require("./errors");
13
+ const log = (0, logger_1.createLogger)();
14
+ const RESPONSE_HEADERS = {
15
+ 'Content-Type': 'text/plain; charset=utf-8',
16
+ 'Transfer-Encoding': 'chunked',
17
+ };
18
+ const JSON_HEADERS = {
19
+ 'Content-Type': 'application/json',
20
+ };
21
+ // ---------------------------------------------------------------------------
22
+ // Default body validator
23
+ // ---------------------------------------------------------------------------
24
+ function defaultValidateBody(body) {
25
+ if (body === null ||
26
+ typeof body !== 'object' ||
27
+ Array.isArray(body) ||
28
+ typeof body['message'] !== 'string') {
29
+ throw new errors_1.AdminAgentRouteBodyError('Expected { message: string }');
30
+ }
31
+ return { message: body['message'] };
32
+ }
33
+ // ---------------------------------------------------------------------------
34
+ // Encoder
35
+ // ---------------------------------------------------------------------------
36
+ const encoder = new TextEncoder();
37
+ function encodeEvent(event) {
38
+ return encoder.encode(JSON.stringify(event) + '\n');
39
+ }
40
+ // ---------------------------------------------------------------------------
41
+ // Factory
42
+ // ---------------------------------------------------------------------------
43
+ /**
44
+ * Creates a Next.js App Router-compatible POST handler that streams
45
+ * `AdminAgentEvent` objects as newline-delimited JSON.
46
+ *
47
+ * Assign directly to `export const POST` in your route file:
48
+ *
49
+ * ```typescript
50
+ * // app/api/chat/admin/route.ts
51
+ * export const POST = createAdminAgentRouteHandler({
52
+ * agent: adminAgent,
53
+ * auth: async (req) => getAuthContextFromRequest(req),
54
+ * });
55
+ * ```
56
+ *
57
+ * @param config - Route configuration including agent, auth, and optional hooks.
58
+ * @returns An async function `(request: Request) => Promise<Response>`.
59
+ */
60
+ function createAdminAgentRouteHandler(config) {
61
+ const validate = config.validateBody ?? defaultValidateBody;
62
+ return async (request) => {
63
+ // ── 1. Parse JSON body ────────────────────────────────────────────────
64
+ let body;
65
+ try {
66
+ body = await request.json();
67
+ }
68
+ catch {
69
+ return new Response(JSON.stringify({ error: 'Failed to parse request body as JSON' }), { status: 400, headers: JSON_HEADERS });
70
+ }
71
+ // ── 2. Validate body ──────────────────────────────────────────────────
72
+ let validated;
73
+ try {
74
+ validated = validate(body);
75
+ }
76
+ catch (err) {
77
+ const detail = err instanceof Error ? err.message : 'Invalid request body';
78
+ return new Response(JSON.stringify({ error: detail }), { status: 400, headers: JSON_HEADERS });
79
+ }
80
+ // ── 3. Auth ───────────────────────────────────────────────────────────
81
+ let authContext;
82
+ try {
83
+ authContext = await config.auth(request);
84
+ }
85
+ catch (err) {
86
+ if (err instanceof errors_1.AdminAgentRouteUnauthorizedError) {
87
+ return new Response(JSON.stringify({ error: err.message }), { status: 401, headers: JSON_HEADERS });
88
+ }
89
+ log.error('[admin-agent-nextjs] Auth error', err instanceof Error ? err : new Error(String(err)));
90
+ return new Response(JSON.stringify({ error: 'Internal server error' }), { status: 500, headers: JSON_HEADERS });
91
+ }
92
+ // ── 4. Peek at first event to catch agent init errors pre-stream ──────
93
+ const iterable = config.agent.chat(validated.message, authContext, request.signal);
94
+ const iterator = iterable[Symbol.asyncIterator]();
95
+ let firstResult;
96
+ try {
97
+ firstResult = await iterator.next();
98
+ }
99
+ catch (err) {
100
+ log.error('[admin-agent-nextjs] Agent init error', err instanceof Error ? err : new Error(String(err)));
101
+ return new Response(JSON.stringify({ error: 'Agent initialization failed' }), { status: 500, headers: JSON_HEADERS });
102
+ }
103
+ // ── 5. Stream events ──────────────────────────────────────────────────
104
+ const { transformEvent } = config;
105
+ const stream = new ReadableStream({
106
+ async start(controller) {
107
+ try {
108
+ let current = firstResult;
109
+ while (!current.done) {
110
+ const event = current.value;
111
+ const isTerminal = event.type === 'rate-limited' || event.type === 'feature-disabled';
112
+ const transformed = transformEvent !== undefined
113
+ ? transformEvent(event)
114
+ : event;
115
+ if (transformed !== null) {
116
+ controller.enqueue(encodeEvent(transformed));
117
+ }
118
+ if (isTerminal) {
119
+ break;
120
+ }
121
+ current = await iterator.next();
122
+ }
123
+ }
124
+ catch (err) {
125
+ log.error('[admin-agent-nextjs] Stream error', err instanceof Error ? err : new Error(String(err)));
126
+ }
127
+ finally {
128
+ controller.close();
129
+ }
130
+ },
131
+ });
132
+ return new Response(stream, {
133
+ status: 200,
134
+ headers: RESPONSE_HEADERS,
135
+ });
136
+ };
137
+ }
138
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @bernierllc/admin-agent-nextjs
3
+ *
4
+ * Thin Next.js App Router adapter that wraps an AdminAgent into a streaming
5
+ * SSE route handler. Handles request parsing, auth extraction, event
6
+ * streaming, and error-to-HTTP mapping.
7
+ *
8
+ * Quick start:
9
+ * ```typescript
10
+ * // app/api/chat/admin/route.ts
11
+ * import { createAdminAgentRouteHandler } from '@bernierllc/admin-agent-nextjs';
12
+ *
13
+ * export const POST = createAdminAgentRouteHandler({
14
+ * agent: adminAgent,
15
+ * auth: async (req) => getAuthContextFromRequest(req),
16
+ * });
17
+ * ```
18
+ */
19
+ export { createAdminAgentRouteHandler } from './handler';
20
+ export type { AdminAgentRouteConfig } from './handler';
21
+ export { AdminAgentRouteError, AdminAgentRouteUnauthorizedError, AdminAgentRouteBodyError, } from './errors';
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,4BAA4B,EAAE,MAAM,WAAW,CAAC;AACzD,YAAY,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAGvD,OAAO,EACL,oBAAoB,EACpB,gCAAgC,EAChC,wBAAwB,GACzB,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.AdminAgentRouteBodyError = exports.AdminAgentRouteUnauthorizedError = exports.AdminAgentRouteError = exports.createAdminAgentRouteHandler = void 0;
11
+ /**
12
+ * @bernierllc/admin-agent-nextjs
13
+ *
14
+ * Thin Next.js App Router adapter that wraps an AdminAgent into a streaming
15
+ * SSE route handler. Handles request parsing, auth extraction, event
16
+ * streaming, and error-to-HTTP mapping.
17
+ *
18
+ * Quick start:
19
+ * ```typescript
20
+ * // app/api/chat/admin/route.ts
21
+ * import { createAdminAgentRouteHandler } from '@bernierllc/admin-agent-nextjs';
22
+ *
23
+ * export const POST = createAdminAgentRouteHandler({
24
+ * agent: adminAgent,
25
+ * auth: async (req) => getAuthContextFromRequest(req),
26
+ * });
27
+ * ```
28
+ */
29
+ // ── Public API ────────────────────────────────────────────────────────────────
30
+ var handler_1 = require("./handler");
31
+ Object.defineProperty(exports, "createAdminAgentRouteHandler", { enumerable: true, get: function () { return handler_1.createAdminAgentRouteHandler; } });
32
+ // ── Errors ────────────────────────────────────────────────────────────────────
33
+ var errors_1 = require("./errors");
34
+ Object.defineProperty(exports, "AdminAgentRouteError", { enumerable: true, get: function () { return errors_1.AdminAgentRouteError; } });
35
+ Object.defineProperty(exports, "AdminAgentRouteUnauthorizedError", { enumerable: true, get: function () { return errors_1.AdminAgentRouteUnauthorizedError; } });
36
+ Object.defineProperty(exports, "AdminAgentRouteBodyError", { enumerable: true, get: function () { return errors_1.AdminAgentRouteBodyError; } });
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;EAME;;;AAEF;;;;;;;;;;;;;;;;;GAiBG;AAEH,iFAAiF;AACjF,qCAAyD;AAAhD,uHAAA,4BAA4B,OAAA;AAGrC,iFAAiF;AACjF,mCAIkB;AAHhB,8GAAA,oBAAoB,OAAA;AACpB,0HAAA,gCAAgC,OAAA;AAChC,kHAAA,wBAAwB,OAAA"}
package/package.json CHANGED
@@ -1,10 +1,71 @@
1
1
  {
2
2
  "name": "@bernierllc/admin-agent-nextjs",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @bernierllc/admin-agent-nextjs",
3
+ "version": "0.1.0",
4
+ "description": "Next.js App Router adapter for admin-agent-service: streaming SSE POST handler with auth, validation, and error mapping",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "browser": false,
5
8
  "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
10
- }
9
+ "admin-agent",
10
+ "nextjs",
11
+ "app-router",
12
+ "streaming",
13
+ "sse",
14
+ "adapter",
15
+ "bernierllc"
16
+ ],
17
+ "author": "Bernier LLC",
18
+ "license": "Bernier LLC",
19
+ "dependencies": {
20
+ "@bernierllc/logger": "^1.7.0",
21
+ "@bernierllc/admin-agent-service": "0.1.0"
22
+ },
23
+ "peerDependencies": {
24
+ "next": ">=14.0.0 <16"
25
+ },
26
+ "devDependencies": {
27
+ "@types/jest": "^29.5.5",
28
+ "@types/node": "^20.6.0",
29
+ "jest": "^29.6.4",
30
+ "next": "^15.0.0",
31
+ "rimraf": "^5.0.1",
32
+ "ts-jest": "^29.1.1",
33
+ "typescript": "^5.2.2"
34
+ },
35
+ "files": [
36
+ "dist/**/*",
37
+ "README.md",
38
+ "LICENSE"
39
+ ],
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "git+https://github.com/bernier-llc/tools.git"
43
+ },
44
+ "engines": {
45
+ "node": ">=18.0.0"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public",
49
+ "registry": "https://registry.npmjs.org/"
50
+ },
51
+ "bernierllc": {
52
+ "runtime": "node",
53
+ "category": "service",
54
+ "integration": {
55
+ "neverhub": "not-applicable",
56
+ "neveradmin": "not-applicable",
57
+ "logger": "integrated"
58
+ }
59
+ },
60
+ "scripts": {
61
+ "build": "tsc",
62
+ "dev": "tsc --watch",
63
+ "test": "jest",
64
+ "test:watch": "jest --watch",
65
+ "test:run": "jest",
66
+ "test:coverage": "jest --coverage",
67
+ "lint": "eslint src/**/*.ts",
68
+ "clean": "rimraf dist",
69
+ "prebuild": "npm run clean"
70
+ }
71
+ }