@ainative/next-sdk 1.0.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.
- package/LICENSE +21 -0
- package/README.md +395 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.esm.js +2 -0
- package/dist/client.esm.js.map +1 -0
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +231 -0
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +230 -0
- package/dist/server.esm.js +2 -0
- package/dist/server.esm.js.map +1 -0
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -0
- package/package.json +98 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AINative Studio
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
# @ainative/next-sdk
|
|
2
|
+
|
|
3
|
+
Official Next.js SDK for AINative Studio API. Provides server and client utilities for both App Router and Pages Router.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Server Components**: Use `createServerClient()` in Server Components and Server Actions
|
|
8
|
+
- **Client Components**: Re-exports `@ainative/react-sdk` hooks for Client Components
|
|
9
|
+
- **API Routes**: Protect routes with `withAuth()` middleware
|
|
10
|
+
- **Session Management**: Extract JWT session from cookies
|
|
11
|
+
- **TypeScript**: Full type safety with TypeScript definitions
|
|
12
|
+
- **Zero Config**: Works out of the box with sensible defaults
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @ainative/next-sdk
|
|
18
|
+
# or
|
|
19
|
+
yarn add @ainative/next-sdk
|
|
20
|
+
# or
|
|
21
|
+
pnpm add @ainative/next-sdk
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
### App Router (Next.js 13+)
|
|
27
|
+
|
|
28
|
+
#### Server Component
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
// app/dashboard/page.tsx
|
|
32
|
+
import { createServerClient, getApiKey } from '@ainative/next-sdk/server';
|
|
33
|
+
import { redirect } from 'next/navigation';
|
|
34
|
+
|
|
35
|
+
export default async function DashboardPage() {
|
|
36
|
+
const apiKey = await getApiKey();
|
|
37
|
+
|
|
38
|
+
if (!apiKey) {
|
|
39
|
+
redirect('/login');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const client = createServerClient({ apiKey });
|
|
43
|
+
const balance = await client.credits.balance();
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<div>
|
|
47
|
+
<h1>Dashboard</h1>
|
|
48
|
+
<p>Credits: {balance.remaining_credits}</p>
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### Client Component
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
// app/chat/page.tsx
|
|
58
|
+
'use client';
|
|
59
|
+
|
|
60
|
+
import { AINativeProvider, useChat } from '@ainative/next-sdk/client';
|
|
61
|
+
|
|
62
|
+
export default function ChatPage({ apiKey }: { apiKey: string }) {
|
|
63
|
+
return (
|
|
64
|
+
<AINativeProvider config={{ apiKey }}>
|
|
65
|
+
<ChatInterface />
|
|
66
|
+
</AINativeProvider>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function ChatInterface() {
|
|
71
|
+
const { messages, isLoading, sendMessage } = useChat();
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<div>
|
|
75
|
+
{messages.map((msg, idx) => (
|
|
76
|
+
<div key={idx}>{msg.content}</div>
|
|
77
|
+
))}
|
|
78
|
+
<button onClick={() => sendMessage('Hello!')}>
|
|
79
|
+
Send
|
|
80
|
+
</button>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### API Route
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
// app/api/chat/route.ts
|
|
90
|
+
import { withAuth, createServerClient } from '@ainative/next-sdk/server';
|
|
91
|
+
import { NextRequest } from 'next/server';
|
|
92
|
+
|
|
93
|
+
export const POST = withAuth(async (req: NextRequest, { session, apiKey }) => {
|
|
94
|
+
const body = await req.json();
|
|
95
|
+
const client = createServerClient({ apiKey });
|
|
96
|
+
|
|
97
|
+
const response = await client.chat.completions.create({
|
|
98
|
+
messages: body.messages,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return Response.json(response);
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Pages Router (Next.js 12)
|
|
106
|
+
|
|
107
|
+
#### Page with Server-Side Rendering
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
// pages/dashboard.tsx
|
|
111
|
+
import { GetServerSideProps } from 'next';
|
|
112
|
+
import { getSessionFromCookie, createServerClient, getApiKeyFromCookie } from '@ainative/next-sdk/server';
|
|
113
|
+
|
|
114
|
+
export default function DashboardPage({ balance }) {
|
|
115
|
+
return <div>Credits: {balance.remaining_credits}</div>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export const getServerSideProps: GetServerSideProps = async ({ req }) => {
|
|
119
|
+
const session = getSessionFromCookie(req.headers.cookie);
|
|
120
|
+
|
|
121
|
+
if (!session) {
|
|
122
|
+
return { redirect: { destination: '/login', permanent: false } };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const apiKey = getApiKeyFromCookie(req.headers.cookie);
|
|
126
|
+
const client = createServerClient({ apiKey });
|
|
127
|
+
const balance = await client.credits.balance();
|
|
128
|
+
|
|
129
|
+
return { props: { balance } };
|
|
130
|
+
};
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
#### API Route
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
// pages/api/chat.ts
|
|
137
|
+
import { withAuthPages, createServerClient } from '@ainative/next-sdk/server';
|
|
138
|
+
|
|
139
|
+
export default withAuthPages(async (req, res, { session, apiKey }) => {
|
|
140
|
+
const client = createServerClient({ apiKey });
|
|
141
|
+
|
|
142
|
+
const response = await client.chat.completions.create({
|
|
143
|
+
messages: req.body.messages,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
res.status(200).json(response);
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## API Reference
|
|
151
|
+
|
|
152
|
+
### Server Utilities
|
|
153
|
+
|
|
154
|
+
#### `createServerClient(config)`
|
|
155
|
+
|
|
156
|
+
Creates a server-side API client for use in Server Components, Server Actions, and API routes.
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { createServerClient } from '@ainative/next-sdk/server';
|
|
160
|
+
|
|
161
|
+
const client = createServerClient({
|
|
162
|
+
apiKey: 'your-jwt-token',
|
|
163
|
+
baseUrl: 'https://api.ainative.studio/api/v1', // optional
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Chat completions
|
|
167
|
+
const response = await client.chat.completions.create({
|
|
168
|
+
messages: [{ role: 'user', content: 'Hello!' }],
|
|
169
|
+
preferred_model: 'gpt-3.5-turbo',
|
|
170
|
+
temperature: 0.7,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Credit balance
|
|
174
|
+
const balance = await client.credits.balance();
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### `getSession()` (App Router)
|
|
178
|
+
|
|
179
|
+
Gets session from cookies in App Router. Returns `Session | null`.
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { getSession } from '@ainative/next-sdk/server';
|
|
183
|
+
|
|
184
|
+
const session = await getSession(); // default cookie: 'ainative_token'
|
|
185
|
+
const session = await getSession('custom_cookie'); // custom cookie name
|
|
186
|
+
|
|
187
|
+
if (session) {
|
|
188
|
+
console.log(session.userId, session.email);
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### `getSessionFromCookie(cookieHeader)` (Pages Router)
|
|
193
|
+
|
|
194
|
+
Gets session from cookie header in Pages Router. Returns `Session | null`.
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
import { getSessionFromCookie } from '@ainative/next-sdk/server';
|
|
198
|
+
|
|
199
|
+
const session = getSessionFromCookie(req.headers.cookie);
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### `getApiKey()` (App Router)
|
|
203
|
+
|
|
204
|
+
Gets JWT token from cookies. Returns `string | null`.
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { getApiKey } from '@ainative/next-sdk/server';
|
|
208
|
+
|
|
209
|
+
const apiKey = await getApiKey();
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
#### `getApiKeyFromCookie(cookieHeader)` (Pages Router)
|
|
213
|
+
|
|
214
|
+
Gets JWT token from cookie header. Returns `string | null`.
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
import { getApiKeyFromCookie } from '@ainative/next-sdk/server';
|
|
218
|
+
|
|
219
|
+
const apiKey = getApiKeyFromCookie(req.headers.cookie);
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### `withAuth(handler, options?)` (App Router)
|
|
223
|
+
|
|
224
|
+
Higher-order function to protect API routes in App Router.
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
import { withAuth } from '@ainative/next-sdk/server';
|
|
228
|
+
|
|
229
|
+
export const POST = withAuth(async (req, { session, apiKey, params }) => {
|
|
230
|
+
// session: Session object
|
|
231
|
+
// apiKey: JWT token string
|
|
232
|
+
// params: Route params (if any)
|
|
233
|
+
|
|
234
|
+
return Response.json({ userId: session.userId });
|
|
235
|
+
}, {
|
|
236
|
+
cookieName: 'ainative_token', // optional
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
#### `withAuthPages(handler, options?)` (Pages Router)
|
|
241
|
+
|
|
242
|
+
Higher-order function to protect API routes in Pages Router.
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
import { withAuthPages } from '@ainative/next-sdk/server';
|
|
246
|
+
|
|
247
|
+
export default withAuthPages(async (req, res, { session, apiKey }) => {
|
|
248
|
+
res.status(200).json({ userId: session.userId });
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Client Utilities
|
|
253
|
+
|
|
254
|
+
All client utilities are re-exported from `@ainative/react-sdk`:
|
|
255
|
+
|
|
256
|
+
- `AINativeProvider` - Provider component for client-side context
|
|
257
|
+
- `useAINative()` - Access API client in client components
|
|
258
|
+
- `useChat()` - Chat completion hook with state management
|
|
259
|
+
- `useCredits()` - Credit balance hook with auto-refresh
|
|
260
|
+
|
|
261
|
+
See [@ainative/react-sdk](https://www.npmjs.com/package/@ainative/react-sdk) for full documentation.
|
|
262
|
+
|
|
263
|
+
## Types
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
import type {
|
|
267
|
+
// Server types
|
|
268
|
+
Session,
|
|
269
|
+
ServerClient,
|
|
270
|
+
ServerClientConfig,
|
|
271
|
+
WithAuthOptions,
|
|
272
|
+
|
|
273
|
+
// Client types
|
|
274
|
+
AINativeConfig,
|
|
275
|
+
Message,
|
|
276
|
+
ChatCompletionRequest,
|
|
277
|
+
ChatCompletionResponse,
|
|
278
|
+
CreditBalance,
|
|
279
|
+
ChatState,
|
|
280
|
+
} from '@ainative/next-sdk';
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Authentication
|
|
284
|
+
|
|
285
|
+
The SDK expects JWT tokens stored in cookies. By default, it looks for a cookie named `ainative_token`.
|
|
286
|
+
|
|
287
|
+
### Setting the Cookie
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
// After login, set the JWT token as a cookie
|
|
291
|
+
import { cookies } from 'next/headers';
|
|
292
|
+
|
|
293
|
+
async function loginHandler(email: string, password: string) {
|
|
294
|
+
// Authenticate with AINative API
|
|
295
|
+
const response = await fetch('https://api.ainative.studio/api/v1/public/auth/login', {
|
|
296
|
+
method: 'POST',
|
|
297
|
+
headers: { 'Content-Type': 'application/json' },
|
|
298
|
+
body: JSON.stringify({ email, password }),
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
const { access_token } = await response.json();
|
|
302
|
+
|
|
303
|
+
// Set cookie
|
|
304
|
+
const cookieStore = await cookies();
|
|
305
|
+
cookieStore.set('ainative_token', access_token, {
|
|
306
|
+
httpOnly: true,
|
|
307
|
+
secure: process.env.NODE_ENV === 'production',
|
|
308
|
+
sameSite: 'lax',
|
|
309
|
+
maxAge: 60 * 60 * 24 * 7, // 7 days
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Custom Cookie Name
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
// Use a custom cookie name
|
|
318
|
+
const session = await getSession('my_custom_token');
|
|
319
|
+
const apiKey = await getApiKey('my_custom_token');
|
|
320
|
+
|
|
321
|
+
export const POST = withAuth(handler, {
|
|
322
|
+
cookieName: 'my_custom_token',
|
|
323
|
+
});
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Middleware Example
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
// middleware.ts
|
|
330
|
+
import { NextResponse } from 'next/server';
|
|
331
|
+
import type { NextRequest } from 'next/server';
|
|
332
|
+
|
|
333
|
+
export function middleware(request: NextRequest) {
|
|
334
|
+
const token = request.cookies.get('ainative_token')?.value;
|
|
335
|
+
const isProtected = request.nextUrl.pathname.startsWith('/dashboard');
|
|
336
|
+
|
|
337
|
+
if (isProtected && !token) {
|
|
338
|
+
return NextResponse.redirect(new URL('/login', request.url));
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return NextResponse.next();
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export const config = {
|
|
345
|
+
matcher: ['/dashboard/:path*'],
|
|
346
|
+
};
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Error Handling
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
try {
|
|
353
|
+
const client = createServerClient({ apiKey });
|
|
354
|
+
const response = await client.chat.completions.create({
|
|
355
|
+
messages: [{ role: 'user', content: 'Hello!' }],
|
|
356
|
+
});
|
|
357
|
+
} catch (error) {
|
|
358
|
+
console.error('API error:', error.message);
|
|
359
|
+
// Handle error appropriately
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Environment Variables
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
# Optional: Override default API URL
|
|
367
|
+
NEXT_PUBLIC_AINATIVE_API_URL=https://api.ainative.studio/api/v1
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## Requirements
|
|
371
|
+
|
|
372
|
+
- Next.js 13.0+ or 14.0+
|
|
373
|
+
- React 18.0+
|
|
374
|
+
- Node.js 18.0+
|
|
375
|
+
|
|
376
|
+
## Examples
|
|
377
|
+
|
|
378
|
+
See the [examples](./examples) directory for complete examples:
|
|
379
|
+
|
|
380
|
+
- [App Router examples](./examples/app-router)
|
|
381
|
+
- [Pages Router examples](./examples/pages-router)
|
|
382
|
+
|
|
383
|
+
## Contributing
|
|
384
|
+
|
|
385
|
+
See the main [repository](https://github.com/AINative-Studio/core) for contribution guidelines.
|
|
386
|
+
|
|
387
|
+
## License
|
|
388
|
+
|
|
389
|
+
MIT
|
|
390
|
+
|
|
391
|
+
## Support
|
|
392
|
+
|
|
393
|
+
- Documentation: https://ainative.studio/docs
|
|
394
|
+
- API Reference: https://api.ainative.studio/docs-enhanced
|
|
395
|
+
- Issues: https://github.com/AINative-Studio/core/issues
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AINativeConfig, AINativeError, AINativeProvider, ChatCompletionRequest, ChatCompletionResponse, ChatState, CreditBalance, Message, Usage, UseChatOptions, UseCreditsReturn, useAINative, useChat, useCredits } from '@ainative/react-sdk';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("@ainative/react-sdk");Object.defineProperty(exports,"AINativeProvider",{enumerable:!0,get:function(){return e.AINativeProvider}}),Object.defineProperty(exports,"useAINative",{enumerable:!0,get:function(){return e.useAINative}}),Object.defineProperty(exports,"useChat",{enumerable:!0,get:function(){return e.useChat}}),Object.defineProperty(exports,"useCredits",{enumerable:!0,get:function(){return e.useCredits}});
|
|
2
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { ChatCompletionRequest, ChatCompletionResponse, CreditBalance } from '@ainative/react-sdk';
|
|
2
|
+
export { AINativeConfig, AINativeError, AINativeProvider, ChatCompletionRequest, ChatCompletionResponse, ChatState, CreditBalance, Message, Usage, UseChatOptions, UseCreditsReturn, useAINative, useChat, useCredits } from '@ainative/react-sdk';
|
|
3
|
+
import { NextRequest } from 'next/server';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* AINative Next.js SDK Type Definitions
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Session data extracted from JWT token
|
|
11
|
+
*/
|
|
12
|
+
interface Session {
|
|
13
|
+
userId: string;
|
|
14
|
+
email: string;
|
|
15
|
+
exp: number;
|
|
16
|
+
iat: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Server-side API client configuration
|
|
20
|
+
*/
|
|
21
|
+
interface ServerClientConfig {
|
|
22
|
+
apiKey: string;
|
|
23
|
+
baseUrl?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Options for withAuth higher-order function
|
|
27
|
+
*/
|
|
28
|
+
interface WithAuthOptions {
|
|
29
|
+
cookieName?: string;
|
|
30
|
+
redirectTo?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Next.js API route request with authentication
|
|
34
|
+
*/
|
|
35
|
+
interface AuthenticatedRequest {
|
|
36
|
+
session: Session;
|
|
37
|
+
apiKey: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Server-side API client for Next.js Server Components
|
|
41
|
+
*/
|
|
42
|
+
interface ServerClient {
|
|
43
|
+
chat: {
|
|
44
|
+
completions: {
|
|
45
|
+
create: (request: ChatCompletionRequest) => Promise<ChatCompletionResponse>;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
credits: {
|
|
49
|
+
balance: () => Promise<CreditBalance>;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Create server-side API client for Next.js Server Components
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Create a server-side API client
|
|
59
|
+
*
|
|
60
|
+
* Use this in Server Components, Server Actions, and API routes.
|
|
61
|
+
*
|
|
62
|
+
* @param config - Client configuration with API key
|
|
63
|
+
* @returns Server-side API client
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```tsx
|
|
67
|
+
* // app/chat/page.tsx
|
|
68
|
+
* import { createServerClient } from '@ainative/next-sdk/server';
|
|
69
|
+
* import { getApiKey } from '@ainative/next-sdk/server';
|
|
70
|
+
*
|
|
71
|
+
* export default async function ChatPage() {
|
|
72
|
+
* const apiKey = await getApiKey();
|
|
73
|
+
* if (!apiKey) return <div>Not authenticated</div>;
|
|
74
|
+
*
|
|
75
|
+
* const client = createServerClient({ apiKey });
|
|
76
|
+
* const balance = await client.credits.balance();
|
|
77
|
+
*
|
|
78
|
+
* return <div>Credits: {balance.remaining_credits}</div>;
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
declare function createServerClient(config: ServerClientConfig): ServerClient;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Get session from JWT token stored in cookies
|
|
86
|
+
*
|
|
87
|
+
* Supports both App Router and Pages Router
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Get session from cookies (App Router)
|
|
92
|
+
*
|
|
93
|
+
* Use this in Server Components and Server Actions.
|
|
94
|
+
*
|
|
95
|
+
* @param cookieName - Cookie name (default: 'ainative_token')
|
|
96
|
+
* @returns Session data or null if not authenticated
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```tsx
|
|
100
|
+
* // app/dashboard/page.tsx
|
|
101
|
+
* import { getSession } from '@ainative/next-sdk/server';
|
|
102
|
+
*
|
|
103
|
+
* export default async function DashboardPage() {
|
|
104
|
+
* const session = await getSession();
|
|
105
|
+
*
|
|
106
|
+
* if (!session) {
|
|
107
|
+
* redirect('/login');
|
|
108
|
+
* }
|
|
109
|
+
*
|
|
110
|
+
* return <div>Welcome {session.email}</div>;
|
|
111
|
+
* }
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
declare function getSession(cookieName?: string): Promise<Session | null>;
|
|
115
|
+
/**
|
|
116
|
+
* Get session from cookies (Pages Router)
|
|
117
|
+
*
|
|
118
|
+
* Use this in getServerSideProps or API routes.
|
|
119
|
+
*
|
|
120
|
+
* @param cookieHeader - Cookie header string from request
|
|
121
|
+
* @param cookieName - Cookie name (default: 'ainative_token')
|
|
122
|
+
* @returns Session data or null if not authenticated
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```tsx
|
|
126
|
+
* // pages/dashboard.tsx
|
|
127
|
+
* import { getSessionFromCookie } from '@ainative/next-sdk/server';
|
|
128
|
+
*
|
|
129
|
+
* export async function getServerSideProps({ req }) {
|
|
130
|
+
* const session = getSessionFromCookie(req.headers.cookie);
|
|
131
|
+
*
|
|
132
|
+
* if (!session) {
|
|
133
|
+
* return { redirect: { destination: '/login', permanent: false } };
|
|
134
|
+
* }
|
|
135
|
+
*
|
|
136
|
+
* return { props: { session } };
|
|
137
|
+
* }
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
declare function getSessionFromCookie(cookieHeader: string | undefined, cookieName?: string): Session | null;
|
|
141
|
+
/**
|
|
142
|
+
* Get API key from cookies (App Router)
|
|
143
|
+
*
|
|
144
|
+
* @param cookieName - Cookie name (default: 'ainative_token')
|
|
145
|
+
* @returns JWT token or null
|
|
146
|
+
*/
|
|
147
|
+
declare function getApiKey(cookieName?: string): Promise<string | null>;
|
|
148
|
+
/**
|
|
149
|
+
* Get API key from cookie header (Pages Router)
|
|
150
|
+
*
|
|
151
|
+
* @param cookieHeader - Cookie header string from request
|
|
152
|
+
* @param cookieName - Cookie name (default: 'ainative_token')
|
|
153
|
+
* @returns JWT token or null
|
|
154
|
+
*/
|
|
155
|
+
declare function getApiKeyFromCookie(cookieHeader: string | undefined, cookieName?: string): string | null;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Higher-order function for API route authentication
|
|
159
|
+
*/
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Request handler with authentication
|
|
163
|
+
*/
|
|
164
|
+
type AuthHandler = (req: NextRequest, context: {
|
|
165
|
+
session: Session;
|
|
166
|
+
apiKey: string;
|
|
167
|
+
params?: any;
|
|
168
|
+
}) => Promise<Response> | Response;
|
|
169
|
+
/**
|
|
170
|
+
* Wrap API route handler with authentication
|
|
171
|
+
*
|
|
172
|
+
* Use this to protect API routes in both App Router and Pages Router.
|
|
173
|
+
*
|
|
174
|
+
* @param handler - Route handler function
|
|
175
|
+
* @param options - Authentication options
|
|
176
|
+
* @returns Protected route handler
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```tsx
|
|
180
|
+
* // app/api/chat/route.ts
|
|
181
|
+
* import { withAuth } from '@ainative/next-sdk/server';
|
|
182
|
+
* import { createServerClient } from '@ainative/next-sdk/server';
|
|
183
|
+
*
|
|
184
|
+
* export const POST = withAuth(async (req, { session, apiKey }) => {
|
|
185
|
+
* const client = createServerClient({ apiKey });
|
|
186
|
+
* const body = await req.json();
|
|
187
|
+
*
|
|
188
|
+
* const response = await client.chat.completions.create({
|
|
189
|
+
* messages: body.messages,
|
|
190
|
+
* });
|
|
191
|
+
*
|
|
192
|
+
* return Response.json(response);
|
|
193
|
+
* });
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
declare function withAuth(handler: AuthHandler, options?: WithAuthOptions): (req: NextRequest, context?: {
|
|
197
|
+
params: any;
|
|
198
|
+
}) => Promise<Response>;
|
|
199
|
+
/**
|
|
200
|
+
* Wrap Pages Router API handler with authentication
|
|
201
|
+
*
|
|
202
|
+
* Use this for API routes in the pages directory.
|
|
203
|
+
*
|
|
204
|
+
* @param handler - Route handler function
|
|
205
|
+
* @param options - Authentication options
|
|
206
|
+
* @returns Protected route handler
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```tsx
|
|
210
|
+
* // pages/api/chat.ts
|
|
211
|
+
* import { withAuthPages } from '@ainative/next-sdk/server';
|
|
212
|
+
* import { createServerClient } from '@ainative/next-sdk/server';
|
|
213
|
+
* import type { NextApiRequest, NextApiResponse } from 'next';
|
|
214
|
+
*
|
|
215
|
+
* export default withAuthPages(async (req, res, { session, apiKey }) => {
|
|
216
|
+
* const client = createServerClient({ apiKey });
|
|
217
|
+
*
|
|
218
|
+
* const response = await client.chat.completions.create({
|
|
219
|
+
* messages: req.body.messages,
|
|
220
|
+
* });
|
|
221
|
+
*
|
|
222
|
+
* res.status(200).json(response);
|
|
223
|
+
* });
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
declare function withAuthPages(handler: (req: any, res: any, context: {
|
|
227
|
+
session: Session;
|
|
228
|
+
apiKey: string;
|
|
229
|
+
}) => Promise<void> | void, options?: WithAuthOptions): (req: any, res: any) => Promise<any>;
|
|
230
|
+
|
|
231
|
+
export { AuthenticatedRequest, ServerClient, ServerClientConfig, Session, WithAuthOptions, createServerClient, getApiKey, getApiKeyFromCookie, getSession, getSessionFromCookie, withAuth, withAuthPages };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{cookies as t}from"next/headers";import{NextResponse as e}from"next/server";export{AINativeProvider,useAINative,useChat,useCredits}from"@ainative/react-sdk";function r(t){const e=t.baseUrl||"https://api.ainative.studio/api/v1";async function r(r,n={}){const a=`${e}${r}`,s=await fetch(a,{...n,headers:{"Content-Type":"application/json",Authorization:`Bearer ${t.apiKey}`,...n.headers}});if(!s.ok){const t=await s.json().catch(()=>({message:`HTTP ${s.status}: ${s.statusText}`}));throw new Error(t.message||`Request failed with status ${s.status}`)}return s.json()}return{chat:{completions:{create:async t=>r("/public/chat/completions",{method:"POST",body:JSON.stringify(t)})}},credits:{balance:async()=>r("/public/credits/balance")}}}function n(t){try{const e=t.split(".");if(3!==e.length)return null;const r=e[1],n=Buffer.from(r,"base64").toString("utf-8"),a=JSON.parse(n);if(!(a.userId&&a.email&&a.exp&&a.iat))return null;const s=Math.floor(Date.now()/1e3);return a.exp<s?null:{userId:a.userId,email:a.email,exp:a.exp,iat:a.iat}}catch(t){return null}}async function a(e="ainative_token"){try{const r=await t(),a=r.get(e)?.value;return a?n(a):null}catch(t){return null}}function s(t,e="ainative_token"){if(!t)return null;const r=t.split(";").map(t=>t.trim()).find(t=>t.startsWith(`${e}=`));if(!r)return null;return n(r.substring(e.length+1))}async function i(e="ainative_token"){try{const r=await t(),n=r.get(e)?.value;return n||null}catch(t){return null}}function o(t,e="ainative_token"){if(!t)return null;const r=t.split(";").map(t=>t.trim()).find(t=>t.startsWith(`${e}=`));return r?r.substring(e.length+1):null}function u(t,r={}){const n=r.cookieName||"ainative_token";return async(r,a)=>{try{const i=r.headers.get("cookie"),u=s(i||void 0,n);if(!u)return e.json({error:"Unauthorized",message:"Authentication required"},{status:401});const c=o(i||void 0,n);return c?await t(r,{session:u,apiKey:c,params:a?.params}):e.json({error:"Unauthorized",message:"API key not found"},{status:401})}catch(t){return console.error("Auth middleware error:",t),e.json({error:"Internal Server Error",message:"Authentication failed"},{status:500})}}}function c(t,e={}){const r=e.cookieName||"ainative_token";return async(e,n)=>{try{const a=e.headers.cookie,i=s(a,r);if(!i)return n.status(401).json({error:"Unauthorized",message:"Authentication required"});const u=o(a,r);return u?await t(e,n,{session:i,apiKey:u}):n.status(401).json({error:"Unauthorized",message:"API key not found"})}catch(t){return console.error("Auth middleware error:",t),n.status(500).json({error:"Internal Server Error",message:"Authentication failed"})}}}export{r as createServerClient,i as getApiKey,o as getApiKeyFromCookie,a as getSession,s as getSessionFromCookie,u as withAuth,c as withAuthPages};
|
|
2
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/server/createServerClient.ts","../src/server/getSession.ts","../src/server/withAuth.ts"],"sourcesContent":["/**\n * Create server-side API client for Next.js Server Components\n */\n\nimport type {\n ServerClient,\n ServerClientConfig,\n ChatCompletionRequest,\n ChatCompletionResponse,\n CreditBalance,\n} from '../types';\n\n/**\n * Create a server-side API client\n *\n * Use this in Server Components, Server Actions, and API routes.\n *\n * @param config - Client configuration with API key\n * @returns Server-side API client\n *\n * @example\n * ```tsx\n * // app/chat/page.tsx\n * import { createServerClient } from '@ainative/next-sdk/server';\n * import { getApiKey } from '@ainative/next-sdk/server';\n *\n * export default async function ChatPage() {\n * const apiKey = await getApiKey();\n * if (!apiKey) return <div>Not authenticated</div>;\n *\n * const client = createServerClient({ apiKey });\n * const balance = await client.credits.balance();\n *\n * return <div>Credits: {balance.remaining_credits}</div>;\n * }\n * ```\n */\nexport function createServerClient(config: ServerClientConfig): ServerClient {\n const baseUrl = config.baseUrl || 'https://api.ainative.studio/api/v1';\n\n /**\n * Make authenticated API request\n */\n async function fetchAPI<T>(endpoint: string, options: RequestInit = {}): Promise<T> {\n const url = `${baseUrl}${endpoint}`;\n\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({\n message: `HTTP ${response.status}: ${response.statusText}`,\n })) as { message?: string };\n\n throw new Error(error.message || `Request failed with status ${response.status}`);\n }\n\n return response.json() as Promise<T>;\n }\n\n return {\n chat: {\n completions: {\n /**\n * Create chat completion\n */\n create: async (request: ChatCompletionRequest): Promise<ChatCompletionResponse> => {\n return fetchAPI<ChatCompletionResponse>('/public/chat/completions', {\n method: 'POST',\n body: JSON.stringify(request),\n });\n },\n },\n },\n credits: {\n /**\n * Get credit balance\n */\n balance: async (): Promise<CreditBalance> => {\n return fetchAPI<CreditBalance>('/public/credits/balance');\n },\n },\n };\n}\n","/**\n * Get session from JWT token stored in cookies\n *\n * Supports both App Router and Pages Router\n */\n\nimport { cookies } from 'next/headers';\nimport type { Session } from '../types';\n\n/**\n * Decode JWT token without verification (server-side only)\n *\n * @param token - JWT token string\n * @returns Decoded session data or null if invalid\n */\nfunction decodeJWT(token: string): Session | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) {\n return null;\n }\n\n const payload = parts[1];\n const decoded = Buffer.from(payload, 'base64').toString('utf-8');\n const parsed = JSON.parse(decoded);\n\n // Validate required fields\n if (!parsed.userId || !parsed.email || !parsed.exp || !parsed.iat) {\n return null;\n }\n\n // Check expiration\n const now = Math.floor(Date.now() / 1000);\n if (parsed.exp < now) {\n return null;\n }\n\n return {\n userId: parsed.userId,\n email: parsed.email,\n exp: parsed.exp,\n iat: parsed.iat,\n };\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Get session from cookies (App Router)\n *\n * Use this in Server Components and Server Actions.\n *\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns Session data or null if not authenticated\n *\n * @example\n * ```tsx\n * // app/dashboard/page.tsx\n * import { getSession } from '@ainative/next-sdk/server';\n *\n * export default async function DashboardPage() {\n * const session = await getSession();\n *\n * if (!session) {\n * redirect('/login');\n * }\n *\n * return <div>Welcome {session.email}</div>;\n * }\n * ```\n */\nexport async function getSession(cookieName = 'ainative_token'): Promise<Session | null> {\n try {\n const cookieStore = await cookies();\n const token = cookieStore.get(cookieName)?.value;\n\n if (!token) {\n return null;\n }\n\n return decodeJWT(token);\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Get session from cookies (Pages Router)\n *\n * Use this in getServerSideProps or API routes.\n *\n * @param cookieHeader - Cookie header string from request\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns Session data or null if not authenticated\n *\n * @example\n * ```tsx\n * // pages/dashboard.tsx\n * import { getSessionFromCookie } from '@ainative/next-sdk/server';\n *\n * export async function getServerSideProps({ req }) {\n * const session = getSessionFromCookie(req.headers.cookie);\n *\n * if (!session) {\n * return { redirect: { destination: '/login', permanent: false } };\n * }\n *\n * return { props: { session } };\n * }\n * ```\n */\nexport function getSessionFromCookie(\n cookieHeader: string | undefined,\n cookieName = 'ainative_token'\n): Session | null {\n if (!cookieHeader) {\n return null;\n }\n\n const cookies = cookieHeader.split(';').map((c) => c.trim());\n const tokenCookie = cookies.find((c) => c.startsWith(`${cookieName}=`));\n\n if (!tokenCookie) {\n return null;\n }\n\n const token = tokenCookie.substring(cookieName.length + 1);\n return decodeJWT(token);\n}\n\n/**\n * Get API key from cookies (App Router)\n *\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns JWT token or null\n */\nexport async function getApiKey(cookieName = 'ainative_token'): Promise<string | null> {\n try {\n const cookieStore = await cookies();\n const token = cookieStore.get(cookieName)?.value;\n return token || null;\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Get API key from cookie header (Pages Router)\n *\n * @param cookieHeader - Cookie header string from request\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns JWT token or null\n */\nexport function getApiKeyFromCookie(\n cookieHeader: string | undefined,\n cookieName = 'ainative_token'\n): string | null {\n if (!cookieHeader) {\n return null;\n }\n\n const cookies = cookieHeader.split(';').map((c) => c.trim());\n const tokenCookie = cookies.find((c) => c.startsWith(`${cookieName}=`));\n\n if (!tokenCookie) {\n return null;\n }\n\n return tokenCookie.substring(cookieName.length + 1);\n}\n","/**\n * Higher-order function for API route authentication\n */\n\nimport type { NextRequest } from 'next/server';\nimport { NextResponse } from 'next/server';\nimport type { WithAuthOptions, Session } from '../types';\nimport { getSessionFromCookie, getApiKeyFromCookie } from './getSession';\n\n/**\n * Request handler with authentication\n */\ntype AuthHandler = (\n req: NextRequest,\n context: { session: Session; apiKey: string; params?: any }\n) => Promise<Response> | Response;\n\n/**\n * Wrap API route handler with authentication\n *\n * Use this to protect API routes in both App Router and Pages Router.\n *\n * @param handler - Route handler function\n * @param options - Authentication options\n * @returns Protected route handler\n *\n * @example\n * ```tsx\n * // app/api/chat/route.ts\n * import { withAuth } from '@ainative/next-sdk/server';\n * import { createServerClient } from '@ainative/next-sdk/server';\n *\n * export const POST = withAuth(async (req, { session, apiKey }) => {\n * const client = createServerClient({ apiKey });\n * const body = await req.json();\n *\n * const response = await client.chat.completions.create({\n * messages: body.messages,\n * });\n *\n * return Response.json(response);\n * });\n * ```\n */\nexport function withAuth(handler: AuthHandler, options: WithAuthOptions = {}) {\n const cookieName = options.cookieName || 'ainative_token';\n\n return async (req: NextRequest, context?: { params: any }) => {\n try {\n // Get cookie from request\n const cookieHeader = req.headers.get('cookie');\n const session = getSessionFromCookie(cookieHeader || undefined, cookieName);\n\n if (!session) {\n return NextResponse.json(\n { error: 'Unauthorized', message: 'Authentication required' },\n { status: 401 }\n );\n }\n\n // Get API key\n const apiKey = getApiKeyFromCookie(cookieHeader || undefined, cookieName);\n\n if (!apiKey) {\n return NextResponse.json(\n { error: 'Unauthorized', message: 'API key not found' },\n { status: 401 }\n );\n }\n\n // Call handler with session and apiKey\n return await handler(req, {\n session,\n apiKey,\n params: context?.params,\n });\n } catch (error) {\n console.error('Auth middleware error:', error);\n return NextResponse.json(\n { error: 'Internal Server Error', message: 'Authentication failed' },\n { status: 500 }\n );\n }\n };\n}\n\n/**\n * Wrap Pages Router API handler with authentication\n *\n * Use this for API routes in the pages directory.\n *\n * @param handler - Route handler function\n * @param options - Authentication options\n * @returns Protected route handler\n *\n * @example\n * ```tsx\n * // pages/api/chat.ts\n * import { withAuthPages } from '@ainative/next-sdk/server';\n * import { createServerClient } from '@ainative/next-sdk/server';\n * import type { NextApiRequest, NextApiResponse } from 'next';\n *\n * export default withAuthPages(async (req, res, { session, apiKey }) => {\n * const client = createServerClient({ apiKey });\n *\n * const response = await client.chat.completions.create({\n * messages: req.body.messages,\n * });\n *\n * res.status(200).json(response);\n * });\n * ```\n */\nexport function withAuthPages(\n handler: (\n req: any,\n res: any,\n context: { session: Session; apiKey: string }\n ) => Promise<void> | void,\n options: WithAuthOptions = {}\n) {\n const cookieName = options.cookieName || 'ainative_token';\n\n return async (req: any, res: any) => {\n try {\n const cookieHeader = req.headers.cookie;\n const session = getSessionFromCookie(cookieHeader, cookieName);\n\n if (!session) {\n return res.status(401).json({\n error: 'Unauthorized',\n message: 'Authentication required',\n });\n }\n\n const apiKey = getApiKeyFromCookie(cookieHeader, cookieName);\n\n if (!apiKey) {\n return res.status(401).json({\n error: 'Unauthorized',\n message: 'API key not found',\n });\n }\n\n return await handler(req, res, { session, apiKey });\n } catch (error) {\n console.error('Auth middleware error:', error);\n return res.status(500).json({\n error: 'Internal Server Error',\n message: 'Authentication failed',\n });\n }\n };\n}\n"],"names":["createServerClient","config","baseUrl","async","fetchAPI","endpoint","options","url","response","fetch","headers","Authorization","apiKey","ok","error","json","catch","message","status","statusText","Error","chat","completions","create","request","method","body","JSON","stringify","credits","balance","decodeJWT","token","parts","split","length","payload","decoded","Buffer","from","toString","parsed","parse","userId","email","exp","iat","now","Math","floor","Date","getSession","cookieName","cookieStore","cookies","get","value","getSessionFromCookie","cookieHeader","tokenCookie","map","c","trim","find","startsWith","substring","getApiKey","getApiKeyFromCookie","withAuth","handler","req","context","session","undefined","NextResponse","params","console","withAuthPages","res","cookie"],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("next/headers"),t=require("next/server"),r=require("@ainative/react-sdk");function n(e){try{const t=e.split(".");if(3!==t.length)return null;const r=t[1],n=Buffer.from(r,"base64").toString("utf-8"),s=JSON.parse(n);if(!(s.userId&&s.email&&s.exp&&s.iat))return null;const o=Math.floor(Date.now()/1e3);return s.exp<o?null:{userId:s.userId,email:s.email,exp:s.exp,iat:s.iat}}catch(e){return null}}function s(e,t="ainative_token"){if(!e)return null;const r=e.split(";").map(e=>e.trim()).find(e=>e.startsWith(`${t}=`));if(!r)return null;return n(r.substring(t.length+1))}function o(e,t="ainative_token"){if(!e)return null;const r=e.split(";").map(e=>e.trim()).find(e=>e.startsWith(`${t}=`));return r?r.substring(t.length+1):null}Object.defineProperty(exports,"AINativeProvider",{enumerable:!0,get:function(){return r.AINativeProvider}}),Object.defineProperty(exports,"useAINative",{enumerable:!0,get:function(){return r.useAINative}}),Object.defineProperty(exports,"useChat",{enumerable:!0,get:function(){return r.useChat}}),Object.defineProperty(exports,"useCredits",{enumerable:!0,get:function(){return r.useCredits}}),exports.createServerClient=function(e){const t=e.baseUrl||"https://api.ainative.studio/api/v1";async function r(r,n={}){const s=`${t}${r}`,o=await fetch(s,{...n,headers:{"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`,...n.headers}});if(!o.ok){const e=await o.json().catch(()=>({message:`HTTP ${o.status}: ${o.statusText}`}));throw new Error(e.message||`Request failed with status ${o.status}`)}return o.json()}return{chat:{completions:{create:async e=>r("/public/chat/completions",{method:"POST",body:JSON.stringify(e)})}},credits:{balance:async()=>r("/public/credits/balance")}}},exports.getApiKey=async function(t="ainative_token"){try{const r=await e.cookies(),n=r.get(t)?.value;return n||null}catch(e){return null}},exports.getApiKeyFromCookie=o,exports.getSession=async function(t="ainative_token"){try{const r=await e.cookies(),s=r.get(t)?.value;return s?n(s):null}catch(e){return null}},exports.getSessionFromCookie=s,exports.withAuth=function(e,r={}){const n=r.cookieName||"ainative_token";return async(r,i)=>{try{const a=r.headers.get("cookie"),u=s(a||void 0,n);if(!u)return t.NextResponse.json({error:"Unauthorized",message:"Authentication required"},{status:401});const c=o(a||void 0,n);return c?await e(r,{session:u,apiKey:c,params:i?.params}):t.NextResponse.json({error:"Unauthorized",message:"API key not found"},{status:401})}catch(e){return console.error("Auth middleware error:",e),t.NextResponse.json({error:"Internal Server Error",message:"Authentication failed"},{status:500})}}},exports.withAuthPages=function(e,t={}){const r=t.cookieName||"ainative_token";return async(t,n)=>{try{const i=t.headers.cookie,a=s(i,r);if(!a)return n.status(401).json({error:"Unauthorized",message:"Authentication required"});const u=o(i,r);return u?await e(t,n,{session:a,apiKey:u}):n.status(401).json({error:"Unauthorized",message:"API key not found"})}catch(e){return console.error("Auth middleware error:",e),n.status(500).json({error:"Internal Server Error",message:"Authentication failed"})}}};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/server/getSession.ts","../src/server/createServerClient.ts","../src/server/withAuth.ts"],"sourcesContent":["/**\n * Get session from JWT token stored in cookies\n *\n * Supports both App Router and Pages Router\n */\n\nimport { cookies } from 'next/headers';\nimport type { Session } from '../types';\n\n/**\n * Decode JWT token without verification (server-side only)\n *\n * @param token - JWT token string\n * @returns Decoded session data or null if invalid\n */\nfunction decodeJWT(token: string): Session | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) {\n return null;\n }\n\n const payload = parts[1];\n const decoded = Buffer.from(payload, 'base64').toString('utf-8');\n const parsed = JSON.parse(decoded);\n\n // Validate required fields\n if (!parsed.userId || !parsed.email || !parsed.exp || !parsed.iat) {\n return null;\n }\n\n // Check expiration\n const now = Math.floor(Date.now() / 1000);\n if (parsed.exp < now) {\n return null;\n }\n\n return {\n userId: parsed.userId,\n email: parsed.email,\n exp: parsed.exp,\n iat: parsed.iat,\n };\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Get session from cookies (App Router)\n *\n * Use this in Server Components and Server Actions.\n *\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns Session data or null if not authenticated\n *\n * @example\n * ```tsx\n * // app/dashboard/page.tsx\n * import { getSession } from '@ainative/next-sdk/server';\n *\n * export default async function DashboardPage() {\n * const session = await getSession();\n *\n * if (!session) {\n * redirect('/login');\n * }\n *\n * return <div>Welcome {session.email}</div>;\n * }\n * ```\n */\nexport async function getSession(cookieName = 'ainative_token'): Promise<Session | null> {\n try {\n const cookieStore = await cookies();\n const token = cookieStore.get(cookieName)?.value;\n\n if (!token) {\n return null;\n }\n\n return decodeJWT(token);\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Get session from cookies (Pages Router)\n *\n * Use this in getServerSideProps or API routes.\n *\n * @param cookieHeader - Cookie header string from request\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns Session data or null if not authenticated\n *\n * @example\n * ```tsx\n * // pages/dashboard.tsx\n * import { getSessionFromCookie } from '@ainative/next-sdk/server';\n *\n * export async function getServerSideProps({ req }) {\n * const session = getSessionFromCookie(req.headers.cookie);\n *\n * if (!session) {\n * return { redirect: { destination: '/login', permanent: false } };\n * }\n *\n * return { props: { session } };\n * }\n * ```\n */\nexport function getSessionFromCookie(\n cookieHeader: string | undefined,\n cookieName = 'ainative_token'\n): Session | null {\n if (!cookieHeader) {\n return null;\n }\n\n const cookies = cookieHeader.split(';').map((c) => c.trim());\n const tokenCookie = cookies.find((c) => c.startsWith(`${cookieName}=`));\n\n if (!tokenCookie) {\n return null;\n }\n\n const token = tokenCookie.substring(cookieName.length + 1);\n return decodeJWT(token);\n}\n\n/**\n * Get API key from cookies (App Router)\n *\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns JWT token or null\n */\nexport async function getApiKey(cookieName = 'ainative_token'): Promise<string | null> {\n try {\n const cookieStore = await cookies();\n const token = cookieStore.get(cookieName)?.value;\n return token || null;\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Get API key from cookie header (Pages Router)\n *\n * @param cookieHeader - Cookie header string from request\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns JWT token or null\n */\nexport function getApiKeyFromCookie(\n cookieHeader: string | undefined,\n cookieName = 'ainative_token'\n): string | null {\n if (!cookieHeader) {\n return null;\n }\n\n const cookies = cookieHeader.split(';').map((c) => c.trim());\n const tokenCookie = cookies.find((c) => c.startsWith(`${cookieName}=`));\n\n if (!tokenCookie) {\n return null;\n }\n\n return tokenCookie.substring(cookieName.length + 1);\n}\n","/**\n * Create server-side API client for Next.js Server Components\n */\n\nimport type {\n ServerClient,\n ServerClientConfig,\n ChatCompletionRequest,\n ChatCompletionResponse,\n CreditBalance,\n} from '../types';\n\n/**\n * Create a server-side API client\n *\n * Use this in Server Components, Server Actions, and API routes.\n *\n * @param config - Client configuration with API key\n * @returns Server-side API client\n *\n * @example\n * ```tsx\n * // app/chat/page.tsx\n * import { createServerClient } from '@ainative/next-sdk/server';\n * import { getApiKey } from '@ainative/next-sdk/server';\n *\n * export default async function ChatPage() {\n * const apiKey = await getApiKey();\n * if (!apiKey) return <div>Not authenticated</div>;\n *\n * const client = createServerClient({ apiKey });\n * const balance = await client.credits.balance();\n *\n * return <div>Credits: {balance.remaining_credits}</div>;\n * }\n * ```\n */\nexport function createServerClient(config: ServerClientConfig): ServerClient {\n const baseUrl = config.baseUrl || 'https://api.ainative.studio/api/v1';\n\n /**\n * Make authenticated API request\n */\n async function fetchAPI<T>(endpoint: string, options: RequestInit = {}): Promise<T> {\n const url = `${baseUrl}${endpoint}`;\n\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({\n message: `HTTP ${response.status}: ${response.statusText}`,\n })) as { message?: string };\n\n throw new Error(error.message || `Request failed with status ${response.status}`);\n }\n\n return response.json() as Promise<T>;\n }\n\n return {\n chat: {\n completions: {\n /**\n * Create chat completion\n */\n create: async (request: ChatCompletionRequest): Promise<ChatCompletionResponse> => {\n return fetchAPI<ChatCompletionResponse>('/public/chat/completions', {\n method: 'POST',\n body: JSON.stringify(request),\n });\n },\n },\n },\n credits: {\n /**\n * Get credit balance\n */\n balance: async (): Promise<CreditBalance> => {\n return fetchAPI<CreditBalance>('/public/credits/balance');\n },\n },\n };\n}\n","/**\n * Higher-order function for API route authentication\n */\n\nimport type { NextRequest } from 'next/server';\nimport { NextResponse } from 'next/server';\nimport type { WithAuthOptions, Session } from '../types';\nimport { getSessionFromCookie, getApiKeyFromCookie } from './getSession';\n\n/**\n * Request handler with authentication\n */\ntype AuthHandler = (\n req: NextRequest,\n context: { session: Session; apiKey: string; params?: any }\n) => Promise<Response> | Response;\n\n/**\n * Wrap API route handler with authentication\n *\n * Use this to protect API routes in both App Router and Pages Router.\n *\n * @param handler - Route handler function\n * @param options - Authentication options\n * @returns Protected route handler\n *\n * @example\n * ```tsx\n * // app/api/chat/route.ts\n * import { withAuth } from '@ainative/next-sdk/server';\n * import { createServerClient } from '@ainative/next-sdk/server';\n *\n * export const POST = withAuth(async (req, { session, apiKey }) => {\n * const client = createServerClient({ apiKey });\n * const body = await req.json();\n *\n * const response = await client.chat.completions.create({\n * messages: body.messages,\n * });\n *\n * return Response.json(response);\n * });\n * ```\n */\nexport function withAuth(handler: AuthHandler, options: WithAuthOptions = {}) {\n const cookieName = options.cookieName || 'ainative_token';\n\n return async (req: NextRequest, context?: { params: any }) => {\n try {\n // Get cookie from request\n const cookieHeader = req.headers.get('cookie');\n const session = getSessionFromCookie(cookieHeader || undefined, cookieName);\n\n if (!session) {\n return NextResponse.json(\n { error: 'Unauthorized', message: 'Authentication required' },\n { status: 401 }\n );\n }\n\n // Get API key\n const apiKey = getApiKeyFromCookie(cookieHeader || undefined, cookieName);\n\n if (!apiKey) {\n return NextResponse.json(\n { error: 'Unauthorized', message: 'API key not found' },\n { status: 401 }\n );\n }\n\n // Call handler with session and apiKey\n return await handler(req, {\n session,\n apiKey,\n params: context?.params,\n });\n } catch (error) {\n console.error('Auth middleware error:', error);\n return NextResponse.json(\n { error: 'Internal Server Error', message: 'Authentication failed' },\n { status: 500 }\n );\n }\n };\n}\n\n/**\n * Wrap Pages Router API handler with authentication\n *\n * Use this for API routes in the pages directory.\n *\n * @param handler - Route handler function\n * @param options - Authentication options\n * @returns Protected route handler\n *\n * @example\n * ```tsx\n * // pages/api/chat.ts\n * import { withAuthPages } from '@ainative/next-sdk/server';\n * import { createServerClient } from '@ainative/next-sdk/server';\n * import type { NextApiRequest, NextApiResponse } from 'next';\n *\n * export default withAuthPages(async (req, res, { session, apiKey }) => {\n * const client = createServerClient({ apiKey });\n *\n * const response = await client.chat.completions.create({\n * messages: req.body.messages,\n * });\n *\n * res.status(200).json(response);\n * });\n * ```\n */\nexport function withAuthPages(\n handler: (\n req: any,\n res: any,\n context: { session: Session; apiKey: string }\n ) => Promise<void> | void,\n options: WithAuthOptions = {}\n) {\n const cookieName = options.cookieName || 'ainative_token';\n\n return async (req: any, res: any) => {\n try {\n const cookieHeader = req.headers.cookie;\n const session = getSessionFromCookie(cookieHeader, cookieName);\n\n if (!session) {\n return res.status(401).json({\n error: 'Unauthorized',\n message: 'Authentication required',\n });\n }\n\n const apiKey = getApiKeyFromCookie(cookieHeader, cookieName);\n\n if (!apiKey) {\n return res.status(401).json({\n error: 'Unauthorized',\n message: 'API key not found',\n });\n }\n\n return await handler(req, res, { session, apiKey });\n } catch (error) {\n console.error('Auth middleware error:', error);\n return res.status(500).json({\n error: 'Internal Server Error',\n message: 'Authentication failed',\n });\n }\n };\n}\n"],"names":["decodeJWT","token","parts","split","length","payload","decoded","Buffer","from","toString","parsed","JSON","parse","userId","email","exp","iat","now","Math","floor","Date","error","getSessionFromCookie","cookieHeader","cookieName","tokenCookie","map","c","trim","find","startsWith","substring","getApiKeyFromCookie","config","baseUrl","async","fetchAPI","endpoint","options","url","response","fetch","headers","Authorization","apiKey","ok","json","catch","message","status","statusText","Error","chat","completions","create","request","method","body","stringify","credits","balance","cookieStore","cookies","get","value","handler","req","context","session","undefined","NextResponse","params","console","res","cookie"],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { ChatCompletionRequest, ChatCompletionResponse, CreditBalance } from '@ainative/react-sdk';
|
|
2
|
+
import { NextRequest } from 'next/server';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* AINative Next.js SDK Type Definitions
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Session data extracted from JWT token
|
|
10
|
+
*/
|
|
11
|
+
interface Session {
|
|
12
|
+
userId: string;
|
|
13
|
+
email: string;
|
|
14
|
+
exp: number;
|
|
15
|
+
iat: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Server-side API client configuration
|
|
19
|
+
*/
|
|
20
|
+
interface ServerClientConfig {
|
|
21
|
+
apiKey: string;
|
|
22
|
+
baseUrl?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Options for withAuth higher-order function
|
|
26
|
+
*/
|
|
27
|
+
interface WithAuthOptions {
|
|
28
|
+
cookieName?: string;
|
|
29
|
+
redirectTo?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Next.js API route request with authentication
|
|
33
|
+
*/
|
|
34
|
+
interface AuthenticatedRequest {
|
|
35
|
+
session: Session;
|
|
36
|
+
apiKey: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Server-side API client for Next.js Server Components
|
|
40
|
+
*/
|
|
41
|
+
interface ServerClient {
|
|
42
|
+
chat: {
|
|
43
|
+
completions: {
|
|
44
|
+
create: (request: ChatCompletionRequest) => Promise<ChatCompletionResponse>;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
credits: {
|
|
48
|
+
balance: () => Promise<CreditBalance>;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Create server-side API client for Next.js Server Components
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Create a server-side API client
|
|
58
|
+
*
|
|
59
|
+
* Use this in Server Components, Server Actions, and API routes.
|
|
60
|
+
*
|
|
61
|
+
* @param config - Client configuration with API key
|
|
62
|
+
* @returns Server-side API client
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```tsx
|
|
66
|
+
* // app/chat/page.tsx
|
|
67
|
+
* import { createServerClient } from '@ainative/next-sdk/server';
|
|
68
|
+
* import { getApiKey } from '@ainative/next-sdk/server';
|
|
69
|
+
*
|
|
70
|
+
* export default async function ChatPage() {
|
|
71
|
+
* const apiKey = await getApiKey();
|
|
72
|
+
* if (!apiKey) return <div>Not authenticated</div>;
|
|
73
|
+
*
|
|
74
|
+
* const client = createServerClient({ apiKey });
|
|
75
|
+
* const balance = await client.credits.balance();
|
|
76
|
+
*
|
|
77
|
+
* return <div>Credits: {balance.remaining_credits}</div>;
|
|
78
|
+
* }
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
declare function createServerClient(config: ServerClientConfig): ServerClient;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Get session from JWT token stored in cookies
|
|
85
|
+
*
|
|
86
|
+
* Supports both App Router and Pages Router
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get session from cookies (App Router)
|
|
91
|
+
*
|
|
92
|
+
* Use this in Server Components and Server Actions.
|
|
93
|
+
*
|
|
94
|
+
* @param cookieName - Cookie name (default: 'ainative_token')
|
|
95
|
+
* @returns Session data or null if not authenticated
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```tsx
|
|
99
|
+
* // app/dashboard/page.tsx
|
|
100
|
+
* import { getSession } from '@ainative/next-sdk/server';
|
|
101
|
+
*
|
|
102
|
+
* export default async function DashboardPage() {
|
|
103
|
+
* const session = await getSession();
|
|
104
|
+
*
|
|
105
|
+
* if (!session) {
|
|
106
|
+
* redirect('/login');
|
|
107
|
+
* }
|
|
108
|
+
*
|
|
109
|
+
* return <div>Welcome {session.email}</div>;
|
|
110
|
+
* }
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
declare function getSession(cookieName?: string): Promise<Session | null>;
|
|
114
|
+
/**
|
|
115
|
+
* Get session from cookies (Pages Router)
|
|
116
|
+
*
|
|
117
|
+
* Use this in getServerSideProps or API routes.
|
|
118
|
+
*
|
|
119
|
+
* @param cookieHeader - Cookie header string from request
|
|
120
|
+
* @param cookieName - Cookie name (default: 'ainative_token')
|
|
121
|
+
* @returns Session data or null if not authenticated
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```tsx
|
|
125
|
+
* // pages/dashboard.tsx
|
|
126
|
+
* import { getSessionFromCookie } from '@ainative/next-sdk/server';
|
|
127
|
+
*
|
|
128
|
+
* export async function getServerSideProps({ req }) {
|
|
129
|
+
* const session = getSessionFromCookie(req.headers.cookie);
|
|
130
|
+
*
|
|
131
|
+
* if (!session) {
|
|
132
|
+
* return { redirect: { destination: '/login', permanent: false } };
|
|
133
|
+
* }
|
|
134
|
+
*
|
|
135
|
+
* return { props: { session } };
|
|
136
|
+
* }
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
declare function getSessionFromCookie(cookieHeader: string | undefined, cookieName?: string): Session | null;
|
|
140
|
+
/**
|
|
141
|
+
* Get API key from cookies (App Router)
|
|
142
|
+
*
|
|
143
|
+
* @param cookieName - Cookie name (default: 'ainative_token')
|
|
144
|
+
* @returns JWT token or null
|
|
145
|
+
*/
|
|
146
|
+
declare function getApiKey(cookieName?: string): Promise<string | null>;
|
|
147
|
+
/**
|
|
148
|
+
* Get API key from cookie header (Pages Router)
|
|
149
|
+
*
|
|
150
|
+
* @param cookieHeader - Cookie header string from request
|
|
151
|
+
* @param cookieName - Cookie name (default: 'ainative_token')
|
|
152
|
+
* @returns JWT token or null
|
|
153
|
+
*/
|
|
154
|
+
declare function getApiKeyFromCookie(cookieHeader: string | undefined, cookieName?: string): string | null;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Higher-order function for API route authentication
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Request handler with authentication
|
|
162
|
+
*/
|
|
163
|
+
type AuthHandler = (req: NextRequest, context: {
|
|
164
|
+
session: Session;
|
|
165
|
+
apiKey: string;
|
|
166
|
+
params?: any;
|
|
167
|
+
}) => Promise<Response> | Response;
|
|
168
|
+
/**
|
|
169
|
+
* Wrap API route handler with authentication
|
|
170
|
+
*
|
|
171
|
+
* Use this to protect API routes in both App Router and Pages Router.
|
|
172
|
+
*
|
|
173
|
+
* @param handler - Route handler function
|
|
174
|
+
* @param options - Authentication options
|
|
175
|
+
* @returns Protected route handler
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```tsx
|
|
179
|
+
* // app/api/chat/route.ts
|
|
180
|
+
* import { withAuth } from '@ainative/next-sdk/server';
|
|
181
|
+
* import { createServerClient } from '@ainative/next-sdk/server';
|
|
182
|
+
*
|
|
183
|
+
* export const POST = withAuth(async (req, { session, apiKey }) => {
|
|
184
|
+
* const client = createServerClient({ apiKey });
|
|
185
|
+
* const body = await req.json();
|
|
186
|
+
*
|
|
187
|
+
* const response = await client.chat.completions.create({
|
|
188
|
+
* messages: body.messages,
|
|
189
|
+
* });
|
|
190
|
+
*
|
|
191
|
+
* return Response.json(response);
|
|
192
|
+
* });
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
declare function withAuth(handler: AuthHandler, options?: WithAuthOptions): (req: NextRequest, context?: {
|
|
196
|
+
params: any;
|
|
197
|
+
}) => Promise<Response>;
|
|
198
|
+
/**
|
|
199
|
+
* Wrap Pages Router API handler with authentication
|
|
200
|
+
*
|
|
201
|
+
* Use this for API routes in the pages directory.
|
|
202
|
+
*
|
|
203
|
+
* @param handler - Route handler function
|
|
204
|
+
* @param options - Authentication options
|
|
205
|
+
* @returns Protected route handler
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```tsx
|
|
209
|
+
* // pages/api/chat.ts
|
|
210
|
+
* import { withAuthPages } from '@ainative/next-sdk/server';
|
|
211
|
+
* import { createServerClient } from '@ainative/next-sdk/server';
|
|
212
|
+
* import type { NextApiRequest, NextApiResponse } from 'next';
|
|
213
|
+
*
|
|
214
|
+
* export default withAuthPages(async (req, res, { session, apiKey }) => {
|
|
215
|
+
* const client = createServerClient({ apiKey });
|
|
216
|
+
*
|
|
217
|
+
* const response = await client.chat.completions.create({
|
|
218
|
+
* messages: req.body.messages,
|
|
219
|
+
* });
|
|
220
|
+
*
|
|
221
|
+
* res.status(200).json(response);
|
|
222
|
+
* });
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
declare function withAuthPages(handler: (req: any, res: any, context: {
|
|
226
|
+
session: Session;
|
|
227
|
+
apiKey: string;
|
|
228
|
+
}) => Promise<void> | void, options?: WithAuthOptions): (req: any, res: any) => Promise<any>;
|
|
229
|
+
|
|
230
|
+
export { AuthenticatedRequest, ServerClient, ServerClientConfig, Session, WithAuthOptions, createServerClient, getApiKey, getApiKeyFromCookie, getSession, getSessionFromCookie, withAuth, withAuthPages };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{cookies as t}from"next/headers";import{NextResponse as e}from"next/server";function n(t){const e=t.baseUrl||"https://api.ainative.studio/api/v1";async function n(n,r={}){const a=`${e}${n}`,s=await fetch(a,{...r,headers:{"Content-Type":"application/json",Authorization:`Bearer ${t.apiKey}`,...r.headers}});if(!s.ok){const t=await s.json().catch(()=>({message:`HTTP ${s.status}: ${s.statusText}`}));throw new Error(t.message||`Request failed with status ${s.status}`)}return s.json()}return{chat:{completions:{create:async t=>n("/public/chat/completions",{method:"POST",body:JSON.stringify(t)})}},credits:{balance:async()=>n("/public/credits/balance")}}}function r(t){try{const e=t.split(".");if(3!==e.length)return null;const n=e[1],r=Buffer.from(n,"base64").toString("utf-8"),a=JSON.parse(r);if(!(a.userId&&a.email&&a.exp&&a.iat))return null;const s=Math.floor(Date.now()/1e3);return a.exp<s?null:{userId:a.userId,email:a.email,exp:a.exp,iat:a.iat}}catch(t){return null}}async function a(e="ainative_token"){try{const n=await t(),a=n.get(e)?.value;return a?r(a):null}catch(t){return null}}function s(t,e="ainative_token"){if(!t)return null;const n=t.split(";").map(t=>t.trim()).find(t=>t.startsWith(`${e}=`));if(!n)return null;return r(n.substring(e.length+1))}async function o(e="ainative_token"){try{const n=await t(),r=n.get(e)?.value;return r||null}catch(t){return null}}function i(t,e="ainative_token"){if(!t)return null;const n=t.split(";").map(t=>t.trim()).find(t=>t.startsWith(`${e}=`));return n?n.substring(e.length+1):null}function u(t,n={}){const r=n.cookieName||"ainative_token";return async(n,a)=>{try{const o=n.headers.get("cookie"),u=s(o||void 0,r);if(!u)return e.json({error:"Unauthorized",message:"Authentication required"},{status:401});const c=i(o||void 0,r);return c?await t(n,{session:u,apiKey:c,params:a?.params}):e.json({error:"Unauthorized",message:"API key not found"},{status:401})}catch(t){return console.error("Auth middleware error:",t),e.json({error:"Internal Server Error",message:"Authentication failed"},{status:500})}}}function c(t,e={}){const n=e.cookieName||"ainative_token";return async(e,r)=>{try{const a=e.headers.cookie,o=s(a,n);if(!o)return r.status(401).json({error:"Unauthorized",message:"Authentication required"});const u=i(a,n);return u?await t(e,r,{session:o,apiKey:u}):r.status(401).json({error:"Unauthorized",message:"API key not found"})}catch(t){return console.error("Auth middleware error:",t),r.status(500).json({error:"Internal Server Error",message:"Authentication failed"})}}}export{n as createServerClient,o as getApiKey,i as getApiKeyFromCookie,a as getSession,s as getSessionFromCookie,u as withAuth,c as withAuthPages};
|
|
2
|
+
//# sourceMappingURL=server.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.esm.js","sources":["../src/server/createServerClient.ts","../src/server/getSession.ts","../src/server/withAuth.ts"],"sourcesContent":["/**\n * Create server-side API client for Next.js Server Components\n */\n\nimport type {\n ServerClient,\n ServerClientConfig,\n ChatCompletionRequest,\n ChatCompletionResponse,\n CreditBalance,\n} from '../types';\n\n/**\n * Create a server-side API client\n *\n * Use this in Server Components, Server Actions, and API routes.\n *\n * @param config - Client configuration with API key\n * @returns Server-side API client\n *\n * @example\n * ```tsx\n * // app/chat/page.tsx\n * import { createServerClient } from '@ainative/next-sdk/server';\n * import { getApiKey } from '@ainative/next-sdk/server';\n *\n * export default async function ChatPage() {\n * const apiKey = await getApiKey();\n * if (!apiKey) return <div>Not authenticated</div>;\n *\n * const client = createServerClient({ apiKey });\n * const balance = await client.credits.balance();\n *\n * return <div>Credits: {balance.remaining_credits}</div>;\n * }\n * ```\n */\nexport function createServerClient(config: ServerClientConfig): ServerClient {\n const baseUrl = config.baseUrl || 'https://api.ainative.studio/api/v1';\n\n /**\n * Make authenticated API request\n */\n async function fetchAPI<T>(endpoint: string, options: RequestInit = {}): Promise<T> {\n const url = `${baseUrl}${endpoint}`;\n\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({\n message: `HTTP ${response.status}: ${response.statusText}`,\n })) as { message?: string };\n\n throw new Error(error.message || `Request failed with status ${response.status}`);\n }\n\n return response.json() as Promise<T>;\n }\n\n return {\n chat: {\n completions: {\n /**\n * Create chat completion\n */\n create: async (request: ChatCompletionRequest): Promise<ChatCompletionResponse> => {\n return fetchAPI<ChatCompletionResponse>('/public/chat/completions', {\n method: 'POST',\n body: JSON.stringify(request),\n });\n },\n },\n },\n credits: {\n /**\n * Get credit balance\n */\n balance: async (): Promise<CreditBalance> => {\n return fetchAPI<CreditBalance>('/public/credits/balance');\n },\n },\n };\n}\n","/**\n * Get session from JWT token stored in cookies\n *\n * Supports both App Router and Pages Router\n */\n\nimport { cookies } from 'next/headers';\nimport type { Session } from '../types';\n\n/**\n * Decode JWT token without verification (server-side only)\n *\n * @param token - JWT token string\n * @returns Decoded session data or null if invalid\n */\nfunction decodeJWT(token: string): Session | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) {\n return null;\n }\n\n const payload = parts[1];\n const decoded = Buffer.from(payload, 'base64').toString('utf-8');\n const parsed = JSON.parse(decoded);\n\n // Validate required fields\n if (!parsed.userId || !parsed.email || !parsed.exp || !parsed.iat) {\n return null;\n }\n\n // Check expiration\n const now = Math.floor(Date.now() / 1000);\n if (parsed.exp < now) {\n return null;\n }\n\n return {\n userId: parsed.userId,\n email: parsed.email,\n exp: parsed.exp,\n iat: parsed.iat,\n };\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Get session from cookies (App Router)\n *\n * Use this in Server Components and Server Actions.\n *\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns Session data or null if not authenticated\n *\n * @example\n * ```tsx\n * // app/dashboard/page.tsx\n * import { getSession } from '@ainative/next-sdk/server';\n *\n * export default async function DashboardPage() {\n * const session = await getSession();\n *\n * if (!session) {\n * redirect('/login');\n * }\n *\n * return <div>Welcome {session.email}</div>;\n * }\n * ```\n */\nexport async function getSession(cookieName = 'ainative_token'): Promise<Session | null> {\n try {\n const cookieStore = await cookies();\n const token = cookieStore.get(cookieName)?.value;\n\n if (!token) {\n return null;\n }\n\n return decodeJWT(token);\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Get session from cookies (Pages Router)\n *\n * Use this in getServerSideProps or API routes.\n *\n * @param cookieHeader - Cookie header string from request\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns Session data or null if not authenticated\n *\n * @example\n * ```tsx\n * // pages/dashboard.tsx\n * import { getSessionFromCookie } from '@ainative/next-sdk/server';\n *\n * export async function getServerSideProps({ req }) {\n * const session = getSessionFromCookie(req.headers.cookie);\n *\n * if (!session) {\n * return { redirect: { destination: '/login', permanent: false } };\n * }\n *\n * return { props: { session } };\n * }\n * ```\n */\nexport function getSessionFromCookie(\n cookieHeader: string | undefined,\n cookieName = 'ainative_token'\n): Session | null {\n if (!cookieHeader) {\n return null;\n }\n\n const cookies = cookieHeader.split(';').map((c) => c.trim());\n const tokenCookie = cookies.find((c) => c.startsWith(`${cookieName}=`));\n\n if (!tokenCookie) {\n return null;\n }\n\n const token = tokenCookie.substring(cookieName.length + 1);\n return decodeJWT(token);\n}\n\n/**\n * Get API key from cookies (App Router)\n *\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns JWT token or null\n */\nexport async function getApiKey(cookieName = 'ainative_token'): Promise<string | null> {\n try {\n const cookieStore = await cookies();\n const token = cookieStore.get(cookieName)?.value;\n return token || null;\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Get API key from cookie header (Pages Router)\n *\n * @param cookieHeader - Cookie header string from request\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns JWT token or null\n */\nexport function getApiKeyFromCookie(\n cookieHeader: string | undefined,\n cookieName = 'ainative_token'\n): string | null {\n if (!cookieHeader) {\n return null;\n }\n\n const cookies = cookieHeader.split(';').map((c) => c.trim());\n const tokenCookie = cookies.find((c) => c.startsWith(`${cookieName}=`));\n\n if (!tokenCookie) {\n return null;\n }\n\n return tokenCookie.substring(cookieName.length + 1);\n}\n","/**\n * Higher-order function for API route authentication\n */\n\nimport type { NextRequest } from 'next/server';\nimport { NextResponse } from 'next/server';\nimport type { WithAuthOptions, Session } from '../types';\nimport { getSessionFromCookie, getApiKeyFromCookie } from './getSession';\n\n/**\n * Request handler with authentication\n */\ntype AuthHandler = (\n req: NextRequest,\n context: { session: Session; apiKey: string; params?: any }\n) => Promise<Response> | Response;\n\n/**\n * Wrap API route handler with authentication\n *\n * Use this to protect API routes in both App Router and Pages Router.\n *\n * @param handler - Route handler function\n * @param options - Authentication options\n * @returns Protected route handler\n *\n * @example\n * ```tsx\n * // app/api/chat/route.ts\n * import { withAuth } from '@ainative/next-sdk/server';\n * import { createServerClient } from '@ainative/next-sdk/server';\n *\n * export const POST = withAuth(async (req, { session, apiKey }) => {\n * const client = createServerClient({ apiKey });\n * const body = await req.json();\n *\n * const response = await client.chat.completions.create({\n * messages: body.messages,\n * });\n *\n * return Response.json(response);\n * });\n * ```\n */\nexport function withAuth(handler: AuthHandler, options: WithAuthOptions = {}) {\n const cookieName = options.cookieName || 'ainative_token';\n\n return async (req: NextRequest, context?: { params: any }) => {\n try {\n // Get cookie from request\n const cookieHeader = req.headers.get('cookie');\n const session = getSessionFromCookie(cookieHeader || undefined, cookieName);\n\n if (!session) {\n return NextResponse.json(\n { error: 'Unauthorized', message: 'Authentication required' },\n { status: 401 }\n );\n }\n\n // Get API key\n const apiKey = getApiKeyFromCookie(cookieHeader || undefined, cookieName);\n\n if (!apiKey) {\n return NextResponse.json(\n { error: 'Unauthorized', message: 'API key not found' },\n { status: 401 }\n );\n }\n\n // Call handler with session and apiKey\n return await handler(req, {\n session,\n apiKey,\n params: context?.params,\n });\n } catch (error) {\n console.error('Auth middleware error:', error);\n return NextResponse.json(\n { error: 'Internal Server Error', message: 'Authentication failed' },\n { status: 500 }\n );\n }\n };\n}\n\n/**\n * Wrap Pages Router API handler with authentication\n *\n * Use this for API routes in the pages directory.\n *\n * @param handler - Route handler function\n * @param options - Authentication options\n * @returns Protected route handler\n *\n * @example\n * ```tsx\n * // pages/api/chat.ts\n * import { withAuthPages } from '@ainative/next-sdk/server';\n * import { createServerClient } from '@ainative/next-sdk/server';\n * import type { NextApiRequest, NextApiResponse } from 'next';\n *\n * export default withAuthPages(async (req, res, { session, apiKey }) => {\n * const client = createServerClient({ apiKey });\n *\n * const response = await client.chat.completions.create({\n * messages: req.body.messages,\n * });\n *\n * res.status(200).json(response);\n * });\n * ```\n */\nexport function withAuthPages(\n handler: (\n req: any,\n res: any,\n context: { session: Session; apiKey: string }\n ) => Promise<void> | void,\n options: WithAuthOptions = {}\n) {\n const cookieName = options.cookieName || 'ainative_token';\n\n return async (req: any, res: any) => {\n try {\n const cookieHeader = req.headers.cookie;\n const session = getSessionFromCookie(cookieHeader, cookieName);\n\n if (!session) {\n return res.status(401).json({\n error: 'Unauthorized',\n message: 'Authentication required',\n });\n }\n\n const apiKey = getApiKeyFromCookie(cookieHeader, cookieName);\n\n if (!apiKey) {\n return res.status(401).json({\n error: 'Unauthorized',\n message: 'API key not found',\n });\n }\n\n return await handler(req, res, { session, apiKey });\n } catch (error) {\n console.error('Auth middleware error:', error);\n return res.status(500).json({\n error: 'Internal Server Error',\n message: 'Authentication failed',\n });\n }\n };\n}\n"],"names":["createServerClient","config","baseUrl","async","fetchAPI","endpoint","options","url","response","fetch","headers","Authorization","apiKey","ok","error","json","catch","message","status","statusText","Error","chat","completions","create","request","method","body","JSON","stringify","credits","balance","decodeJWT","token","parts","split","length","payload","decoded","Buffer","from","toString","parsed","parse","userId","email","exp","iat","now","Math","floor","Date","getSession","cookieName","cookieStore","cookies","get","value","getSessionFromCookie","cookieHeader","tokenCookie","map","c","trim","find","startsWith","substring","getApiKey","getApiKeyFromCookie","withAuth","handler","req","context","session","undefined","NextResponse","params","console","withAuthPages","res","cookie"],"mappings":"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"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("next/headers"),t=require("next/server");function r(e){try{const t=e.split(".");if(3!==t.length)return null;const r=t[1],n=Buffer.from(r,"base64").toString("utf-8"),s=JSON.parse(n);if(!(s.userId&&s.email&&s.exp&&s.iat))return null;const o=Math.floor(Date.now()/1e3);return s.exp<o?null:{userId:s.userId,email:s.email,exp:s.exp,iat:s.iat}}catch(e){return null}}function n(e,t="ainative_token"){if(!e)return null;const n=e.split(";").map(e=>e.trim()).find(e=>e.startsWith(`${t}=`));if(!n)return null;return r(n.substring(t.length+1))}function s(e,t="ainative_token"){if(!e)return null;const r=e.split(";").map(e=>e.trim()).find(e=>e.startsWith(`${t}=`));return r?r.substring(t.length+1):null}exports.createServerClient=function(e){const t=e.baseUrl||"https://api.ainative.studio/api/v1";async function r(r,n={}){const s=`${t}${r}`,o=await fetch(s,{...n,headers:{"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`,...n.headers}});if(!o.ok){const e=await o.json().catch(()=>({message:`HTTP ${o.status}: ${o.statusText}`}));throw new Error(e.message||`Request failed with status ${o.status}`)}return o.json()}return{chat:{completions:{create:async e=>r("/public/chat/completions",{method:"POST",body:JSON.stringify(e)})}},credits:{balance:async()=>r("/public/credits/balance")}}},exports.getApiKey=async function(t="ainative_token"){try{const r=await e.cookies(),n=r.get(t)?.value;return n||null}catch(e){return null}},exports.getApiKeyFromCookie=s,exports.getSession=async function(t="ainative_token"){try{const n=await e.cookies(),s=n.get(t)?.value;return s?r(s):null}catch(e){return null}},exports.getSessionFromCookie=n,exports.withAuth=function(e,r={}){const o=r.cookieName||"ainative_token";return async(r,a)=>{try{const i=r.headers.get("cookie"),u=n(i||void 0,o);if(!u)return t.NextResponse.json({error:"Unauthorized",message:"Authentication required"},{status:401});const c=s(i||void 0,o);return c?await e(r,{session:u,apiKey:c,params:a?.params}):t.NextResponse.json({error:"Unauthorized",message:"API key not found"},{status:401})}catch(e){return console.error("Auth middleware error:",e),t.NextResponse.json({error:"Internal Server Error",message:"Authentication failed"},{status:500})}}},exports.withAuthPages=function(e,t={}){const r=t.cookieName||"ainative_token";return async(t,o)=>{try{const a=t.headers.cookie,i=n(a,r);if(!i)return o.status(401).json({error:"Unauthorized",message:"Authentication required"});const u=s(a,r);return u?await e(t,o,{session:i,apiKey:u}):o.status(401).json({error:"Unauthorized",message:"API key not found"})}catch(e){return console.error("Auth middleware error:",e),o.status(500).json({error:"Internal Server Error",message:"Authentication failed"})}}};
|
|
2
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sources":["../src/server/getSession.ts","../src/server/createServerClient.ts","../src/server/withAuth.ts"],"sourcesContent":["/**\n * Get session from JWT token stored in cookies\n *\n * Supports both App Router and Pages Router\n */\n\nimport { cookies } from 'next/headers';\nimport type { Session } from '../types';\n\n/**\n * Decode JWT token without verification (server-side only)\n *\n * @param token - JWT token string\n * @returns Decoded session data or null if invalid\n */\nfunction decodeJWT(token: string): Session | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) {\n return null;\n }\n\n const payload = parts[1];\n const decoded = Buffer.from(payload, 'base64').toString('utf-8');\n const parsed = JSON.parse(decoded);\n\n // Validate required fields\n if (!parsed.userId || !parsed.email || !parsed.exp || !parsed.iat) {\n return null;\n }\n\n // Check expiration\n const now = Math.floor(Date.now() / 1000);\n if (parsed.exp < now) {\n return null;\n }\n\n return {\n userId: parsed.userId,\n email: parsed.email,\n exp: parsed.exp,\n iat: parsed.iat,\n };\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Get session from cookies (App Router)\n *\n * Use this in Server Components and Server Actions.\n *\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns Session data or null if not authenticated\n *\n * @example\n * ```tsx\n * // app/dashboard/page.tsx\n * import { getSession } from '@ainative/next-sdk/server';\n *\n * export default async function DashboardPage() {\n * const session = await getSession();\n *\n * if (!session) {\n * redirect('/login');\n * }\n *\n * return <div>Welcome {session.email}</div>;\n * }\n * ```\n */\nexport async function getSession(cookieName = 'ainative_token'): Promise<Session | null> {\n try {\n const cookieStore = await cookies();\n const token = cookieStore.get(cookieName)?.value;\n\n if (!token) {\n return null;\n }\n\n return decodeJWT(token);\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Get session from cookies (Pages Router)\n *\n * Use this in getServerSideProps or API routes.\n *\n * @param cookieHeader - Cookie header string from request\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns Session data or null if not authenticated\n *\n * @example\n * ```tsx\n * // pages/dashboard.tsx\n * import { getSessionFromCookie } from '@ainative/next-sdk/server';\n *\n * export async function getServerSideProps({ req }) {\n * const session = getSessionFromCookie(req.headers.cookie);\n *\n * if (!session) {\n * return { redirect: { destination: '/login', permanent: false } };\n * }\n *\n * return { props: { session } };\n * }\n * ```\n */\nexport function getSessionFromCookie(\n cookieHeader: string | undefined,\n cookieName = 'ainative_token'\n): Session | null {\n if (!cookieHeader) {\n return null;\n }\n\n const cookies = cookieHeader.split(';').map((c) => c.trim());\n const tokenCookie = cookies.find((c) => c.startsWith(`${cookieName}=`));\n\n if (!tokenCookie) {\n return null;\n }\n\n const token = tokenCookie.substring(cookieName.length + 1);\n return decodeJWT(token);\n}\n\n/**\n * Get API key from cookies (App Router)\n *\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns JWT token or null\n */\nexport async function getApiKey(cookieName = 'ainative_token'): Promise<string | null> {\n try {\n const cookieStore = await cookies();\n const token = cookieStore.get(cookieName)?.value;\n return token || null;\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Get API key from cookie header (Pages Router)\n *\n * @param cookieHeader - Cookie header string from request\n * @param cookieName - Cookie name (default: 'ainative_token')\n * @returns JWT token or null\n */\nexport function getApiKeyFromCookie(\n cookieHeader: string | undefined,\n cookieName = 'ainative_token'\n): string | null {\n if (!cookieHeader) {\n return null;\n }\n\n const cookies = cookieHeader.split(';').map((c) => c.trim());\n const tokenCookie = cookies.find((c) => c.startsWith(`${cookieName}=`));\n\n if (!tokenCookie) {\n return null;\n }\n\n return tokenCookie.substring(cookieName.length + 1);\n}\n","/**\n * Create server-side API client for Next.js Server Components\n */\n\nimport type {\n ServerClient,\n ServerClientConfig,\n ChatCompletionRequest,\n ChatCompletionResponse,\n CreditBalance,\n} from '../types';\n\n/**\n * Create a server-side API client\n *\n * Use this in Server Components, Server Actions, and API routes.\n *\n * @param config - Client configuration with API key\n * @returns Server-side API client\n *\n * @example\n * ```tsx\n * // app/chat/page.tsx\n * import { createServerClient } from '@ainative/next-sdk/server';\n * import { getApiKey } from '@ainative/next-sdk/server';\n *\n * export default async function ChatPage() {\n * const apiKey = await getApiKey();\n * if (!apiKey) return <div>Not authenticated</div>;\n *\n * const client = createServerClient({ apiKey });\n * const balance = await client.credits.balance();\n *\n * return <div>Credits: {balance.remaining_credits}</div>;\n * }\n * ```\n */\nexport function createServerClient(config: ServerClientConfig): ServerClient {\n const baseUrl = config.baseUrl || 'https://api.ainative.studio/api/v1';\n\n /**\n * Make authenticated API request\n */\n async function fetchAPI<T>(endpoint: string, options: RequestInit = {}): Promise<T> {\n const url = `${baseUrl}${endpoint}`;\n\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({\n message: `HTTP ${response.status}: ${response.statusText}`,\n })) as { message?: string };\n\n throw new Error(error.message || `Request failed with status ${response.status}`);\n }\n\n return response.json() as Promise<T>;\n }\n\n return {\n chat: {\n completions: {\n /**\n * Create chat completion\n */\n create: async (request: ChatCompletionRequest): Promise<ChatCompletionResponse> => {\n return fetchAPI<ChatCompletionResponse>('/public/chat/completions', {\n method: 'POST',\n body: JSON.stringify(request),\n });\n },\n },\n },\n credits: {\n /**\n * Get credit balance\n */\n balance: async (): Promise<CreditBalance> => {\n return fetchAPI<CreditBalance>('/public/credits/balance');\n },\n },\n };\n}\n","/**\n * Higher-order function for API route authentication\n */\n\nimport type { NextRequest } from 'next/server';\nimport { NextResponse } from 'next/server';\nimport type { WithAuthOptions, Session } from '../types';\nimport { getSessionFromCookie, getApiKeyFromCookie } from './getSession';\n\n/**\n * Request handler with authentication\n */\ntype AuthHandler = (\n req: NextRequest,\n context: { session: Session; apiKey: string; params?: any }\n) => Promise<Response> | Response;\n\n/**\n * Wrap API route handler with authentication\n *\n * Use this to protect API routes in both App Router and Pages Router.\n *\n * @param handler - Route handler function\n * @param options - Authentication options\n * @returns Protected route handler\n *\n * @example\n * ```tsx\n * // app/api/chat/route.ts\n * import { withAuth } from '@ainative/next-sdk/server';\n * import { createServerClient } from '@ainative/next-sdk/server';\n *\n * export const POST = withAuth(async (req, { session, apiKey }) => {\n * const client = createServerClient({ apiKey });\n * const body = await req.json();\n *\n * const response = await client.chat.completions.create({\n * messages: body.messages,\n * });\n *\n * return Response.json(response);\n * });\n * ```\n */\nexport function withAuth(handler: AuthHandler, options: WithAuthOptions = {}) {\n const cookieName = options.cookieName || 'ainative_token';\n\n return async (req: NextRequest, context?: { params: any }) => {\n try {\n // Get cookie from request\n const cookieHeader = req.headers.get('cookie');\n const session = getSessionFromCookie(cookieHeader || undefined, cookieName);\n\n if (!session) {\n return NextResponse.json(\n { error: 'Unauthorized', message: 'Authentication required' },\n { status: 401 }\n );\n }\n\n // Get API key\n const apiKey = getApiKeyFromCookie(cookieHeader || undefined, cookieName);\n\n if (!apiKey) {\n return NextResponse.json(\n { error: 'Unauthorized', message: 'API key not found' },\n { status: 401 }\n );\n }\n\n // Call handler with session and apiKey\n return await handler(req, {\n session,\n apiKey,\n params: context?.params,\n });\n } catch (error) {\n console.error('Auth middleware error:', error);\n return NextResponse.json(\n { error: 'Internal Server Error', message: 'Authentication failed' },\n { status: 500 }\n );\n }\n };\n}\n\n/**\n * Wrap Pages Router API handler with authentication\n *\n * Use this for API routes in the pages directory.\n *\n * @param handler - Route handler function\n * @param options - Authentication options\n * @returns Protected route handler\n *\n * @example\n * ```tsx\n * // pages/api/chat.ts\n * import { withAuthPages } from '@ainative/next-sdk/server';\n * import { createServerClient } from '@ainative/next-sdk/server';\n * import type { NextApiRequest, NextApiResponse } from 'next';\n *\n * export default withAuthPages(async (req, res, { session, apiKey }) => {\n * const client = createServerClient({ apiKey });\n *\n * const response = await client.chat.completions.create({\n * messages: req.body.messages,\n * });\n *\n * res.status(200).json(response);\n * });\n * ```\n */\nexport function withAuthPages(\n handler: (\n req: any,\n res: any,\n context: { session: Session; apiKey: string }\n ) => Promise<void> | void,\n options: WithAuthOptions = {}\n) {\n const cookieName = options.cookieName || 'ainative_token';\n\n return async (req: any, res: any) => {\n try {\n const cookieHeader = req.headers.cookie;\n const session = getSessionFromCookie(cookieHeader, cookieName);\n\n if (!session) {\n return res.status(401).json({\n error: 'Unauthorized',\n message: 'Authentication required',\n });\n }\n\n const apiKey = getApiKeyFromCookie(cookieHeader, cookieName);\n\n if (!apiKey) {\n return res.status(401).json({\n error: 'Unauthorized',\n message: 'API key not found',\n });\n }\n\n return await handler(req, res, { session, apiKey });\n } catch (error) {\n console.error('Auth middleware error:', error);\n return res.status(500).json({\n error: 'Internal Server Error',\n message: 'Authentication failed',\n });\n }\n };\n}\n"],"names":["decodeJWT","token","parts","split","length","payload","decoded","Buffer","from","toString","parsed","JSON","parse","userId","email","exp","iat","now","Math","floor","Date","error","getSessionFromCookie","cookieHeader","cookieName","tokenCookie","map","c","trim","find","startsWith","substring","getApiKeyFromCookie","config","baseUrl","async","fetchAPI","endpoint","options","url","response","fetch","headers","Authorization","apiKey","ok","json","catch","message","status","statusText","Error","chat","completions","create","request","method","body","stringify","credits","balance","cookieStore","cookies","get","value","handler","req","context","session","undefined","NextResponse","params","console","res","cookie"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ainative/next-sdk",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Official Next.js SDK for AINative Studio API - Server and client utilities for App Router and Pages Router",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.esm.js",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./server": {
|
|
15
|
+
"types": "./dist/server.d.ts",
|
|
16
|
+
"import": "./dist/server.esm.js",
|
|
17
|
+
"require": "./dist/server.js"
|
|
18
|
+
},
|
|
19
|
+
"./client": {
|
|
20
|
+
"types": "./dist/client.d.ts",
|
|
21
|
+
"import": "./dist/client.esm.js",
|
|
22
|
+
"require": "./dist/client.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "rollup -c rollup.config.mjs",
|
|
32
|
+
"build:watch": "rollup -c -w",
|
|
33
|
+
"test": "jest",
|
|
34
|
+
"test:watch": "jest --watch",
|
|
35
|
+
"test:coverage": "jest --coverage",
|
|
36
|
+
"lint": "eslint . --ext .ts,.tsx",
|
|
37
|
+
"lint:fix": "eslint . --ext .ts,.tsx --fix",
|
|
38
|
+
"type-check": "tsc --noEmit",
|
|
39
|
+
"prepublishOnly": "npm run test && npm run build"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"ainative",
|
|
43
|
+
"nextjs",
|
|
44
|
+
"next",
|
|
45
|
+
"react",
|
|
46
|
+
"server-components",
|
|
47
|
+
"app-router",
|
|
48
|
+
"pages-router",
|
|
49
|
+
"api",
|
|
50
|
+
"sdk",
|
|
51
|
+
"chat",
|
|
52
|
+
"ai",
|
|
53
|
+
"typescript"
|
|
54
|
+
],
|
|
55
|
+
"author": "AINative Studio",
|
|
56
|
+
"license": "MIT",
|
|
57
|
+
"repository": {
|
|
58
|
+
"type": "git",
|
|
59
|
+
"url": "https://github.com/AINative-Studio/ainative-sdks"
|
|
60
|
+
},
|
|
61
|
+
"bugs": {
|
|
62
|
+
"url": "https://github.com/AINative-Studio/ainative-sdks/issues"
|
|
63
|
+
},
|
|
64
|
+
"homepage": "https://ainative.studio",
|
|
65
|
+
"peerDependencies": {
|
|
66
|
+
"next": "^13.0.0 || ^14.0.0",
|
|
67
|
+
"react": "^18.0.0"
|
|
68
|
+
},
|
|
69
|
+
"dependencies": {
|
|
70
|
+
"@ainative/react-sdk": "^1.0.0"
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
74
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
75
|
+
"@rollup/plugin-typescript": "^11.1.5",
|
|
76
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
77
|
+
"@types/jest": "^29.5.10",
|
|
78
|
+
"@types/node": "^20.10.0",
|
|
79
|
+
"@types/react": "^18.2.45",
|
|
80
|
+
"@typescript-eslint/eslint-plugin": "^6.13.0",
|
|
81
|
+
"@typescript-eslint/parser": "^6.13.0",
|
|
82
|
+
"eslint": "^8.54.0",
|
|
83
|
+
"eslint-plugin-react": "^7.33.2",
|
|
84
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
85
|
+
"jest": "^29.7.0",
|
|
86
|
+
"jest-environment-node": "^29.7.0",
|
|
87
|
+
"next": "^14.0.0",
|
|
88
|
+
"react": "^18.2.0",
|
|
89
|
+
"rollup": "^3.29.4",
|
|
90
|
+
"rollup-plugin-dts": "^5.3.1",
|
|
91
|
+
"ts-jest": "^29.1.1",
|
|
92
|
+
"tslib": "^2.6.2",
|
|
93
|
+
"typescript": "^5.3.2"
|
|
94
|
+
},
|
|
95
|
+
"engines": {
|
|
96
|
+
"node": ">=18.0.0"
|
|
97
|
+
}
|
|
98
|
+
}
|