@insforge/sdk 1.4.2 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -135
- package/SDK-REFERENCE.md +146 -168
- package/dist/{client-BR9o-WUm.d.ts → client-BZyLCjO1.d.mts} +62 -122
- package/dist/{client-C-qBRoea.d.mts → client-Dh7GOydb.d.ts} +62 -122
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +585 -428
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +588 -428
- package/dist/index.mjs.map +1 -1
- package/dist/{middleware-Tu_RlUAt.d.ts → middleware-CicBLgnO.d.ts} +1 -1
- package/dist/{middleware-K59XjpUX.d.mts → middleware-o3zPqPvY.d.mts} +1 -1
- package/dist/ssr/middleware.d.mts +2 -2
- package/dist/ssr/middleware.d.ts +2 -2
- package/dist/ssr/middleware.js +71 -52
- package/dist/ssr/middleware.js.map +1 -1
- package/dist/ssr/middleware.mjs +71 -52
- package/dist/ssr/middleware.mjs.map +1 -1
- package/dist/ssr.d.mts +4 -4
- package/dist/ssr.d.ts +4 -4
- package/dist/ssr.js +680 -544
- package/dist/ssr.js.map +1 -1
- package/dist/ssr.mjs +684 -545
- package/dist/ssr.mjs.map +1 -1
- package/dist/{types-Dk-44JJf.d.mts → types-MKmYAYeg.d.mts} +12 -0
- package/dist/{types-Dk-44JJf.d.ts → types-MKmYAYeg.d.ts} +12 -0
- package/package.json +12 -5
package/SDK-REFERENCE.md
CHANGED
|
@@ -9,11 +9,11 @@ npm install @insforge/sdk
|
|
|
9
9
|
## Initialize
|
|
10
10
|
|
|
11
11
|
```javascript
|
|
12
|
-
import { createClient } from
|
|
12
|
+
import { createClient } from '@insforge/sdk';
|
|
13
13
|
|
|
14
14
|
const insforge = createClient({
|
|
15
|
-
baseUrl:
|
|
16
|
-
anonKey:
|
|
15
|
+
baseUrl: 'http://localhost:7130',
|
|
16
|
+
anonKey: 'your-anon-key',
|
|
17
17
|
});
|
|
18
18
|
```
|
|
19
19
|
|
|
@@ -22,10 +22,10 @@ const insforge = createClient({
|
|
|
22
22
|
## Admin Client
|
|
23
23
|
|
|
24
24
|
```typescript
|
|
25
|
-
import { createAdminClient } from
|
|
25
|
+
import { createAdminClient } from '@insforge/sdk';
|
|
26
26
|
|
|
27
27
|
const admin = createAdminClient({
|
|
28
|
-
baseUrl:
|
|
28
|
+
baseUrl: 'http://localhost:7130',
|
|
29
29
|
apiKey: process.env.INSFORGE_API_KEY!,
|
|
30
30
|
});
|
|
31
31
|
```
|
|
@@ -50,10 +50,10 @@ Default cookies:
|
|
|
50
50
|
### `createBrowserClient()`
|
|
51
51
|
|
|
52
52
|
```typescript
|
|
53
|
-
import { createBrowserClient } from
|
|
53
|
+
import { createBrowserClient } from '@insforge/sdk/ssr';
|
|
54
54
|
|
|
55
55
|
const insforge = createBrowserClient({
|
|
56
|
-
refreshUrl:
|
|
56
|
+
refreshUrl: '/api/auth/refresh', // default
|
|
57
57
|
});
|
|
58
58
|
```
|
|
59
59
|
|
|
@@ -66,8 +66,8 @@ not include auth mutations such as `signInWithPassword()`, `signUp()`, or
|
|
|
66
66
|
### `createServerClient()`
|
|
67
67
|
|
|
68
68
|
```typescript
|
|
69
|
-
import { cookies } from
|
|
70
|
-
import { createServerClient } from
|
|
69
|
+
import { cookies } from 'next/headers';
|
|
70
|
+
import { createServerClient } from '@insforge/sdk/ssr';
|
|
71
71
|
|
|
72
72
|
const insforge = createServerClient({
|
|
73
73
|
cookies: await cookies(),
|
|
@@ -80,7 +80,7 @@ The server client reads only the access-token cookie and passes it as the per-re
|
|
|
80
80
|
|
|
81
81
|
```typescript
|
|
82
82
|
// app/api/auth/refresh/route.ts
|
|
83
|
-
import { createRefreshAuthRouter } from
|
|
83
|
+
import { createRefreshAuthRouter } from '@insforge/sdk/ssr';
|
|
84
84
|
|
|
85
85
|
export const { POST } = createRefreshAuthRouter();
|
|
86
86
|
```
|
|
@@ -92,17 +92,17 @@ safe fields.
|
|
|
92
92
|
|
|
93
93
|
```typescript
|
|
94
94
|
// app/actions.ts
|
|
95
|
-
|
|
95
|
+
'use server';
|
|
96
96
|
|
|
97
|
-
import { cookies } from
|
|
98
|
-
import { createAuthActions } from
|
|
97
|
+
import { cookies } from 'next/headers';
|
|
98
|
+
import { createAuthActions } from '@insforge/sdk/ssr';
|
|
99
99
|
|
|
100
100
|
export async function signIn(formData: FormData) {
|
|
101
101
|
const auth = createAuthActions({ cookies: await cookies() });
|
|
102
102
|
|
|
103
103
|
const { data, error } = await auth.signInWithPassword({
|
|
104
|
-
email: String(formData.get(
|
|
105
|
-
password: String(formData.get(
|
|
104
|
+
email: String(formData.get('email')),
|
|
105
|
+
password: String(formData.get('password')),
|
|
106
106
|
});
|
|
107
107
|
|
|
108
108
|
return { user: data?.user ?? null, error };
|
|
@@ -122,7 +122,7 @@ auto-exchange OAuth callbacks.
|
|
|
122
122
|
Use `refreshAuth()` directly when the route needs app-specific logic:
|
|
123
123
|
|
|
124
124
|
```typescript
|
|
125
|
-
import { refreshAuth } from
|
|
125
|
+
import { refreshAuth } from '@insforge/sdk/ssr';
|
|
126
126
|
|
|
127
127
|
export async function POST(request: Request) {
|
|
128
128
|
await beforeRefresh(request);
|
|
@@ -140,8 +140,8 @@ bundling the full SDK client.
|
|
|
140
140
|
|
|
141
141
|
```typescript
|
|
142
142
|
// proxy.ts on Next.js 16+, middleware.ts on Next.js 15 and earlier
|
|
143
|
-
import { NextResponse, type NextRequest } from
|
|
144
|
-
import { updateSession } from
|
|
143
|
+
import { NextResponse, type NextRequest } from 'next/server';
|
|
144
|
+
import { updateSession } from '@insforge/sdk/ssr/middleware';
|
|
145
145
|
|
|
146
146
|
export async function proxy(request: NextRequest) {
|
|
147
147
|
const response = NextResponse.next({ request });
|
|
@@ -171,7 +171,7 @@ The SDK automatically detects and handles OAuth callback parameters when initial
|
|
|
171
171
|
```javascript
|
|
172
172
|
// Just initialize the client - OAuth is handled automatically
|
|
173
173
|
const insforge = createClient({
|
|
174
|
-
baseUrl:
|
|
174
|
+
baseUrl: 'http://localhost:7130',
|
|
175
175
|
});
|
|
176
176
|
|
|
177
177
|
// If the URL contains OAuth callback parameters like:
|
|
@@ -192,10 +192,10 @@ const { data } = await insforge.auth.getCurrentUser();
|
|
|
192
192
|
|
|
193
193
|
```javascript
|
|
194
194
|
await insforge.auth.signUp({
|
|
195
|
-
email:
|
|
196
|
-
password:
|
|
197
|
-
name:
|
|
198
|
-
redirectTo:
|
|
195
|
+
email: 'user@example.com',
|
|
196
|
+
password: 'password123',
|
|
197
|
+
name: 'John Doe', // optional
|
|
198
|
+
redirectTo: 'http://localhost:3000/sign-in', // optional, recommended for link-based verification
|
|
199
199
|
});
|
|
200
200
|
// Response: { data: { user, accessToken }, error }
|
|
201
201
|
// user: { id, email, name, emailVerified, createdAt, updatedAt }
|
|
@@ -215,8 +215,8 @@ Recommended: use your sign-in page as `redirectTo`, then show a success message
|
|
|
215
215
|
|
|
216
216
|
```javascript
|
|
217
217
|
await insforge.auth.signInWithPassword({
|
|
218
|
-
email:
|
|
219
|
-
password:
|
|
218
|
+
email: 'user@example.com',
|
|
219
|
+
password: 'password123',
|
|
220
220
|
});
|
|
221
221
|
// Response: { data: { user, accessToken }, error }
|
|
222
222
|
// user: { id, email, name, emailVerified, createdAt, updatedAt }
|
|
@@ -226,9 +226,9 @@ await insforge.auth.signInWithPassword({
|
|
|
226
226
|
### `signInWithOAuth()`
|
|
227
227
|
|
|
228
228
|
```javascript
|
|
229
|
-
await insforge.auth.signInWithOAuth(
|
|
230
|
-
redirectTo:
|
|
231
|
-
additionalParams: { prompt:
|
|
229
|
+
await insforge.auth.signInWithOAuth('google', {
|
|
230
|
+
redirectTo: 'http://localhost:3000/dashboard',
|
|
231
|
+
additionalParams: { prompt: 'select_account' }, // optional provider-specific OAuth params
|
|
232
232
|
skipBrowserRedirect: true, // optional, returns URL instead of redirecting
|
|
233
233
|
});
|
|
234
234
|
// Response: { data: { url, provider }, error }
|
|
@@ -280,10 +280,10 @@ await insforge.auth.getProfile(userId);
|
|
|
280
280
|
|
|
281
281
|
```javascript
|
|
282
282
|
await insforge.auth.setProfile({
|
|
283
|
-
nickname:
|
|
284
|
-
avatar_url:
|
|
285
|
-
bio:
|
|
286
|
-
birthday:
|
|
283
|
+
nickname: 'JohnDoe',
|
|
284
|
+
avatar_url: 'https://...',
|
|
285
|
+
bio: 'Software developer',
|
|
286
|
+
birthday: '1990-01-01',
|
|
287
287
|
});
|
|
288
288
|
// Response: { data: profile, error }
|
|
289
289
|
// Updates current user's profile in users table
|
|
@@ -302,8 +302,8 @@ await insforge.auth.getPublicAuthConfig();
|
|
|
302
302
|
|
|
303
303
|
```javascript
|
|
304
304
|
await insforge.auth.resendVerificationEmail({
|
|
305
|
-
email:
|
|
306
|
-
redirectTo:
|
|
305
|
+
email: 'user@example.com',
|
|
306
|
+
redirectTo: 'http://localhost:3000/sign-in', // optional, recommended for link-based verification
|
|
307
307
|
});
|
|
308
308
|
// Response: { data: { success, message }, error }
|
|
309
309
|
```
|
|
@@ -312,8 +312,8 @@ await insforge.auth.resendVerificationEmail({
|
|
|
312
312
|
|
|
313
313
|
```javascript
|
|
314
314
|
await insforge.auth.verifyEmail({
|
|
315
|
-
email:
|
|
316
|
-
otp:
|
|
315
|
+
email: 'user@example.com',
|
|
316
|
+
otp: '123456',
|
|
317
317
|
});
|
|
318
318
|
// Response: { data: { user, accessToken, csrfToken?, refreshToken? }, error }
|
|
319
319
|
// POST /api/auth/email/verify is code-only
|
|
@@ -328,8 +328,8 @@ await insforge.auth.verifyEmail({
|
|
|
328
328
|
|
|
329
329
|
```javascript
|
|
330
330
|
await insforge.auth.sendResetPasswordEmail({
|
|
331
|
-
email:
|
|
332
|
-
redirectTo:
|
|
331
|
+
email: 'user@example.com',
|
|
332
|
+
redirectTo: 'http://localhost:3000/reset-password', // optional, recommended for link-based reset
|
|
333
333
|
});
|
|
334
334
|
// Response: { data: { success, message }, error }
|
|
335
335
|
```
|
|
@@ -338,8 +338,8 @@ await insforge.auth.sendResetPasswordEmail({
|
|
|
338
338
|
|
|
339
339
|
```javascript
|
|
340
340
|
await insforge.auth.exchangeResetPasswordToken({
|
|
341
|
-
email:
|
|
342
|
-
code:
|
|
341
|
+
email: 'user@example.com',
|
|
342
|
+
code: '123456',
|
|
343
343
|
});
|
|
344
344
|
// Response: { data: { token, expiresAt }, error }
|
|
345
345
|
```
|
|
@@ -348,8 +348,8 @@ await insforge.auth.exchangeResetPasswordToken({
|
|
|
348
348
|
|
|
349
349
|
```javascript
|
|
350
350
|
await insforge.auth.resetPassword({
|
|
351
|
-
newPassword:
|
|
352
|
-
otp:
|
|
351
|
+
newPassword: 'newSecurePassword123',
|
|
352
|
+
otp: 'reset-token',
|
|
353
353
|
});
|
|
354
354
|
// Response: { data: { message }, error }
|
|
355
355
|
// Browser reset links use GET /api/auth/email/reset-password-link first,
|
|
@@ -401,16 +401,13 @@ Payments methods are provider-scoped and intended for generated app frontends. T
|
|
|
401
401
|
### `stripe.createCheckoutSession()`
|
|
402
402
|
|
|
403
403
|
```javascript
|
|
404
|
-
const { data, error } = await insforge.payments.stripe.createCheckoutSession(
|
|
405
|
-
|
|
406
|
-
{
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
idempotencyKey: "cart_123", // optional, recommended for retry-safe checkout creation
|
|
412
|
-
},
|
|
413
|
-
);
|
|
404
|
+
const { data, error } = await insforge.payments.stripe.createCheckoutSession('test', {
|
|
405
|
+
mode: 'payment',
|
|
406
|
+
lineItems: [{ priceId: 'price_123', quantity: 1 }],
|
|
407
|
+
successUrl: 'https://example.com/success',
|
|
408
|
+
cancelUrl: 'https://example.com/pricing',
|
|
409
|
+
idempotencyKey: 'cart_123', // optional, recommended for retry-safe checkout creation
|
|
410
|
+
});
|
|
414
411
|
|
|
415
412
|
if (!error && data?.checkoutSession.url) {
|
|
416
413
|
window.location.assign(data.checkoutSession.url);
|
|
@@ -420,23 +417,22 @@ if (!error && data?.checkoutSession.url) {
|
|
|
420
417
|
For one-time payments, `subject` is optional. For subscription checkout, `subject` is required because subscriptions represent ongoing entitlement for an app-defined billing owner.
|
|
421
418
|
|
|
422
419
|
```javascript
|
|
423
|
-
await insforge.payments.stripe.createCheckoutSession(
|
|
424
|
-
mode:
|
|
425
|
-
subject: { type:
|
|
426
|
-
lineItems: [{ priceId:
|
|
427
|
-
successUrl:
|
|
428
|
-
cancelUrl:
|
|
420
|
+
await insforge.payments.stripe.createCheckoutSession('test', {
|
|
421
|
+
mode: 'subscription',
|
|
422
|
+
subject: { type: 'team', id: 'team_123' },
|
|
423
|
+
lineItems: [{ priceId: 'price_monthly_123', quantity: 1 }],
|
|
424
|
+
successUrl: 'https://example.com/billing/success',
|
|
425
|
+
cancelUrl: 'https://example.com/billing',
|
|
429
426
|
});
|
|
430
427
|
```
|
|
431
428
|
|
|
432
429
|
### `stripe.createCustomerPortalSession()`
|
|
433
430
|
|
|
434
431
|
```javascript
|
|
435
|
-
const { data, error } =
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
});
|
|
432
|
+
const { data, error } = await insforge.payments.stripe.createCustomerPortalSession('test', {
|
|
433
|
+
subject: { type: 'team', id: 'team_123' },
|
|
434
|
+
returnUrl: 'https://example.com/billing',
|
|
435
|
+
});
|
|
440
436
|
|
|
441
437
|
if (!error && data?.customerPortalSession.url) {
|
|
442
438
|
window.location.assign(data.customerPortalSession.url);
|
|
@@ -450,20 +446,20 @@ Customer portal sessions require an authenticated user and an existing Stripe cu
|
|
|
450
446
|
Razorpay uses Checkout.js instead of a hosted redirect URL. Create an order through InsForge, pass `checkoutOptions` into Razorpay Checkout.js, then verify the signed payment response.
|
|
451
447
|
|
|
452
448
|
```javascript
|
|
453
|
-
const { data, error } = await insforge.payments.razorpay.createOrder(
|
|
449
|
+
const { data, error } = await insforge.payments.razorpay.createOrder('test', {
|
|
454
450
|
amount: 200000,
|
|
455
|
-
currency:
|
|
456
|
-
receipt:
|
|
457
|
-
subject: { type:
|
|
458
|
-
customerName:
|
|
459
|
-
customerEmail:
|
|
451
|
+
currency: 'INR',
|
|
452
|
+
receipt: 'cart_123',
|
|
453
|
+
subject: { type: 'team', id: 'team_123' },
|
|
454
|
+
customerName: 'Ada Lovelace',
|
|
455
|
+
customerEmail: 'ada@example.com',
|
|
460
456
|
});
|
|
461
457
|
|
|
462
458
|
if (!error && data) {
|
|
463
459
|
const checkout = new Razorpay({
|
|
464
460
|
...data.checkoutOptions,
|
|
465
461
|
handler: async (response) => {
|
|
466
|
-
await insforge.payments.razorpay.verifyOrder(
|
|
462
|
+
await insforge.payments.razorpay.verifyOrder('test', {
|
|
467
463
|
orderId: response.razorpay_order_id,
|
|
468
464
|
paymentId: response.razorpay_payment_id,
|
|
469
465
|
signature: response.razorpay_signature,
|
|
@@ -478,22 +474,19 @@ if (!error && data) {
|
|
|
478
474
|
### `razorpay.createSubscription()`
|
|
479
475
|
|
|
480
476
|
```javascript
|
|
481
|
-
const { data, error } = await insforge.payments.razorpay.createSubscription(
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
customerEmail: "ada@example.com",
|
|
489
|
-
},
|
|
490
|
-
);
|
|
477
|
+
const { data, error } = await insforge.payments.razorpay.createSubscription('test', {
|
|
478
|
+
planId: 'plan_123',
|
|
479
|
+
totalCount: 12,
|
|
480
|
+
subject: { type: 'team', id: 'team_123' },
|
|
481
|
+
customerName: 'Ada Lovelace',
|
|
482
|
+
customerEmail: 'ada@example.com',
|
|
483
|
+
});
|
|
491
484
|
|
|
492
485
|
if (!error && data) {
|
|
493
486
|
const checkout = new Razorpay({
|
|
494
487
|
...data.checkoutOptions,
|
|
495
488
|
handler: async (response) => {
|
|
496
|
-
await insforge.payments.razorpay.verifySubscription(
|
|
489
|
+
await insforge.payments.razorpay.verifySubscription('test', {
|
|
497
490
|
subscriptionId: response.razorpay_subscription_id,
|
|
498
491
|
paymentId: response.razorpay_payment_id,
|
|
499
492
|
signature: response.razorpay_signature,
|
|
@@ -508,7 +501,7 @@ if (!error && data) {
|
|
|
508
501
|
### `razorpay.cancelSubscription()`
|
|
509
502
|
|
|
510
503
|
```javascript
|
|
511
|
-
await insforge.payments.razorpay.cancelSubscription(
|
|
504
|
+
await insforge.payments.razorpay.cancelSubscription('test', 'sub_123', {
|
|
512
505
|
cancelAtCycleEnd: false,
|
|
513
506
|
});
|
|
514
507
|
```
|
|
@@ -516,8 +509,8 @@ await insforge.payments.razorpay.cancelSubscription("test", "sub_123", {
|
|
|
516
509
|
### `razorpay.pauseSubscription()` / `razorpay.resumeSubscription()`
|
|
517
510
|
|
|
518
511
|
```javascript
|
|
519
|
-
await insforge.payments.razorpay.pauseSubscription(
|
|
520
|
-
await insforge.payments.razorpay.resumeSubscription(
|
|
512
|
+
await insforge.payments.razorpay.pauseSubscription('test', 'sub_123');
|
|
513
|
+
await insforge.payments.razorpay.resumeSubscription('test', 'sub_123');
|
|
521
514
|
```
|
|
522
515
|
|
|
523
516
|
Razorpay webhook setup is manual in the Razorpay dashboard. Configure keys and copy the webhook URL, secret, and recommended events from the InsForge payments settings UI.
|
|
@@ -531,7 +524,7 @@ Razorpay webhook setup is manual in the Razorpay dashboard. Configure keys and c
|
|
|
531
524
|
Create a query builder for a table:
|
|
532
525
|
|
|
533
526
|
```javascript
|
|
534
|
-
const query = insforge.database.from(
|
|
527
|
+
const query = insforge.database.from('posts');
|
|
535
528
|
// Returns a PostgREST query builder with all Supabase features
|
|
536
529
|
```
|
|
537
530
|
|
|
@@ -539,29 +532,27 @@ const query = insforge.database.from("posts");
|
|
|
539
532
|
|
|
540
533
|
```javascript
|
|
541
534
|
// Basic select
|
|
542
|
-
await insforge.database.from(
|
|
535
|
+
await insforge.database.from('posts').select(); // Default: '*'
|
|
543
536
|
|
|
544
537
|
// Select specific columns
|
|
545
|
-
await insforge.database.from(
|
|
538
|
+
await insforge.database.from('posts').select('id, title, created_at');
|
|
546
539
|
|
|
547
540
|
// With filters
|
|
548
541
|
await insforge.database
|
|
549
|
-
.from(
|
|
542
|
+
.from('posts')
|
|
550
543
|
.select()
|
|
551
|
-
.eq(
|
|
552
|
-
.order(
|
|
544
|
+
.eq('user_id', '123')
|
|
545
|
+
.order('created_at', { ascending: false })
|
|
553
546
|
.limit(10);
|
|
554
547
|
|
|
555
548
|
// With joins (PostgREST syntax)
|
|
556
|
-
await insforge.database.from(
|
|
549
|
+
await insforge.database.from('posts').select('*, users!inner(*)'); // Inner join with users table
|
|
557
550
|
|
|
558
551
|
// Join with specific columns
|
|
559
|
-
await insforge.database
|
|
560
|
-
.from("posts")
|
|
561
|
-
.select("id, title, users(nickname, avatar_url)");
|
|
552
|
+
await insforge.database.from('posts').select('id, title, users(nickname, avatar_url)');
|
|
562
553
|
|
|
563
554
|
// Aliased joins
|
|
564
|
-
await insforge.database.from(
|
|
555
|
+
await insforge.database.from('posts').select('*, author:users(*)'); // Alias users as author
|
|
565
556
|
// Response: { data: [...], error }
|
|
566
557
|
```
|
|
567
558
|
|
|
@@ -569,25 +560,19 @@ await insforge.database.from("posts").select("*, author:users(*)"); // Alias use
|
|
|
569
560
|
|
|
570
561
|
```javascript
|
|
571
562
|
// Single record - use .select() to return inserted data
|
|
572
|
-
await insforge.database
|
|
573
|
-
.from("posts")
|
|
574
|
-
.insert({ title: "Hello", content: "World" })
|
|
575
|
-
.select();
|
|
563
|
+
await insforge.database.from('posts').insert({ title: 'Hello', content: 'World' }).select();
|
|
576
564
|
|
|
577
565
|
// Multiple records
|
|
578
566
|
await insforge.database
|
|
579
|
-
.from(
|
|
567
|
+
.from('posts')
|
|
580
568
|
.insert([
|
|
581
|
-
{ title:
|
|
582
|
-
{ title:
|
|
569
|
+
{ title: 'Post 1', content: 'Content 1' },
|
|
570
|
+
{ title: 'Post 2', content: 'Content 2' },
|
|
583
571
|
])
|
|
584
572
|
.select();
|
|
585
573
|
|
|
586
574
|
// Upsert
|
|
587
|
-
await insforge.database
|
|
588
|
-
.from("posts")
|
|
589
|
-
.upsert({ id: "123", title: "Updated or New" })
|
|
590
|
-
.select();
|
|
575
|
+
await insforge.database.from('posts').upsert({ id: '123', title: 'Updated or New' }).select();
|
|
591
576
|
// Response: { data: [...], error }
|
|
592
577
|
|
|
593
578
|
// Note: Without .select(), mutations return { data: null, error }
|
|
@@ -596,18 +581,14 @@ await insforge.database
|
|
|
596
581
|
### UPDATE Operations
|
|
597
582
|
|
|
598
583
|
```javascript
|
|
599
|
-
await insforge.database
|
|
600
|
-
.from("posts")
|
|
601
|
-
.update({ title: "Updated Title" })
|
|
602
|
-
.eq("id", "123")
|
|
603
|
-
.select();
|
|
584
|
+
await insforge.database.from('posts').update({ title: 'Updated Title' }).eq('id', '123').select();
|
|
604
585
|
// Response: { data: [...], error }
|
|
605
586
|
```
|
|
606
587
|
|
|
607
588
|
### DELETE Operations
|
|
608
589
|
|
|
609
590
|
```javascript
|
|
610
|
-
await insforge.database.from(
|
|
591
|
+
await insforge.database.from('posts').delete().eq('id', '123').select();
|
|
611
592
|
// Response: { data: [...], error }
|
|
612
593
|
```
|
|
613
594
|
|
|
@@ -635,28 +616,25 @@ await insforge.database.from("posts").delete().eq("id", "123").select();
|
|
|
635
616
|
|
|
636
617
|
```javascript
|
|
637
618
|
// Simple OR: status = 'active' OR status = 'pending'
|
|
638
|
-
await insforge.database
|
|
639
|
-
.from("posts")
|
|
640
|
-
.select()
|
|
641
|
-
.or("status.eq.active,status.eq.pending");
|
|
619
|
+
await insforge.database.from('posts').select().or('status.eq.active,status.eq.pending');
|
|
642
620
|
|
|
643
621
|
// OR with other filters (implicit AND)
|
|
644
622
|
await insforge.database
|
|
645
|
-
.from(
|
|
623
|
+
.from('posts')
|
|
646
624
|
.select()
|
|
647
|
-
.eq(
|
|
648
|
-
.or(
|
|
625
|
+
.eq('user_id', '123') // AND
|
|
626
|
+
.or('status.eq.draft,status.eq.published'); // OR
|
|
649
627
|
|
|
650
628
|
// Complex OR with NOT
|
|
651
|
-
await insforge.database.from(
|
|
629
|
+
await insforge.database.from('users').select().or('age.lt.18,age.gt.65');
|
|
652
630
|
// age < 18 OR age > 65
|
|
653
631
|
|
|
654
632
|
// Combining AND and OR
|
|
655
633
|
await insforge.database
|
|
656
|
-
.from(
|
|
634
|
+
.from('products')
|
|
657
635
|
.select()
|
|
658
|
-
.eq(
|
|
659
|
-
.or(
|
|
636
|
+
.eq('category', 'electronics')
|
|
637
|
+
.or('price.lt.100,rating.gte.4.5');
|
|
660
638
|
// category = 'electronics' AND (price < 100 OR rating >= 4.5)
|
|
661
639
|
```
|
|
662
640
|
|
|
@@ -678,13 +656,13 @@ Use with `select()` to get counts:
|
|
|
678
656
|
```javascript
|
|
679
657
|
// Get exact count with data
|
|
680
658
|
const { data, count, error } = await insforge.database
|
|
681
|
-
.from(
|
|
682
|
-
.select(
|
|
659
|
+
.from('posts')
|
|
660
|
+
.select('*', { count: 'exact' });
|
|
683
661
|
|
|
684
662
|
// Get count without data (HEAD request)
|
|
685
663
|
const { count, error } = await insforge.database
|
|
686
|
-
.from(
|
|
687
|
-
.select(
|
|
664
|
+
.from('posts')
|
|
665
|
+
.select('*', { count: 'exact', head: true });
|
|
688
666
|
|
|
689
667
|
// Count strategies:
|
|
690
668
|
// 'exact' - Accurate but slower for large tables
|
|
@@ -698,26 +676,26 @@ All methods return the query builder for chaining:
|
|
|
698
676
|
|
|
699
677
|
```javascript
|
|
700
678
|
const { data, error } = await insforge.database
|
|
701
|
-
.from(
|
|
702
|
-
.select(
|
|
703
|
-
.eq(
|
|
704
|
-
.gte(
|
|
705
|
-
.order(
|
|
679
|
+
.from('posts')
|
|
680
|
+
.select('id, title, content')
|
|
681
|
+
.eq('status', 'published')
|
|
682
|
+
.gte('likes', 100)
|
|
683
|
+
.order('created_at', { ascending: false })
|
|
706
684
|
.limit(10);
|
|
707
685
|
|
|
708
686
|
// With count (Supabase-style)
|
|
709
687
|
const { data, error, count } = await insforge.database
|
|
710
|
-
.from(
|
|
711
|
-
.select(
|
|
712
|
-
.eq(
|
|
688
|
+
.from('posts')
|
|
689
|
+
.select('*', { count: 'exact' }) // Request exact count
|
|
690
|
+
.eq('status', 'published')
|
|
713
691
|
.range(0, 9); // Get first 10
|
|
714
692
|
// Returns: data (array), error (PostgrestError), count (number)
|
|
715
693
|
|
|
716
694
|
// Count without data (head request)
|
|
717
695
|
const { count, error } = await insforge.database
|
|
718
|
-
.from(
|
|
719
|
-
.select(
|
|
720
|
-
.eq(
|
|
696
|
+
.from('posts')
|
|
697
|
+
.select('*', { count: 'exact', head: true })
|
|
698
|
+
.eq('status', 'published');
|
|
721
699
|
// Returns only count, no data
|
|
722
700
|
```
|
|
723
701
|
|
|
@@ -726,14 +704,14 @@ const { count, error } = await insforge.database
|
|
|
726
704
|
### `storage.from()`
|
|
727
705
|
|
|
728
706
|
```javascript
|
|
729
|
-
const bucket = insforge.storage.from(
|
|
707
|
+
const bucket = insforge.storage.from('avatars');
|
|
730
708
|
// Returns StorageBucket instance for file operations
|
|
731
709
|
```
|
|
732
710
|
|
|
733
711
|
### `bucket.upload()`
|
|
734
712
|
|
|
735
713
|
```javascript
|
|
736
|
-
await bucket.upload(
|
|
714
|
+
await bucket.upload('path/file.jpg', file);
|
|
737
715
|
// Response: { data: StorageFileSchema, error }
|
|
738
716
|
// data: { bucket, key, size, mimeType, uploadedAt, url }
|
|
739
717
|
```
|
|
@@ -749,14 +727,14 @@ await bucket.uploadAuto(file);
|
|
|
749
727
|
### `bucket.download()`
|
|
750
728
|
|
|
751
729
|
```javascript
|
|
752
|
-
await bucket.download(
|
|
730
|
+
await bucket.download('path/file.jpg');
|
|
753
731
|
// Response: { data: Blob, error }
|
|
754
732
|
```
|
|
755
733
|
|
|
756
734
|
### `bucket.list()`
|
|
757
735
|
|
|
758
736
|
```javascript
|
|
759
|
-
await bucket.list({ prefix:
|
|
737
|
+
await bucket.list({ prefix: 'users/', limit: 10 });
|
|
760
738
|
// Response: { data: ListObjectsResponseSchema, error }
|
|
761
739
|
// data: { bucketName, objects[], pagination }
|
|
762
740
|
```
|
|
@@ -764,14 +742,14 @@ await bucket.list({ prefix: "users/", limit: 10 });
|
|
|
764
742
|
### `bucket.remove()`
|
|
765
743
|
|
|
766
744
|
```javascript
|
|
767
|
-
await bucket.remove(
|
|
745
|
+
await bucket.remove('path/file.jpg');
|
|
768
746
|
// Response: { data: { message }, error }
|
|
769
747
|
```
|
|
770
748
|
|
|
771
749
|
### `bucket.getPublicUrl()`
|
|
772
750
|
|
|
773
751
|
```javascript
|
|
774
|
-
bucket.getPublicUrl(
|
|
752
|
+
bucket.getPublicUrl('path/file.jpg');
|
|
775
753
|
// Returns: string URL (no API call)
|
|
776
754
|
```
|
|
777
755
|
|
|
@@ -785,10 +763,10 @@ Create AI chat completions with support for both streaming and non-streaming res
|
|
|
785
763
|
|
|
786
764
|
```javascript
|
|
787
765
|
const completion = await insforge.ai.chat.completions.create({
|
|
788
|
-
model:
|
|
766
|
+
model: 'anthropic/claude-3.5-haiku',
|
|
789
767
|
messages: [
|
|
790
|
-
{ role:
|
|
791
|
-
{ role:
|
|
768
|
+
{ role: 'system', content: 'You are a helpful assistant' },
|
|
769
|
+
{ role: 'user', content: 'Hello, how are you?' },
|
|
792
770
|
],
|
|
793
771
|
temperature: 0.7,
|
|
794
772
|
maxTokens: 500,
|
|
@@ -805,8 +783,8 @@ console.log(completion.choices[0].message.content);
|
|
|
805
783
|
```javascript
|
|
806
784
|
// Returns an async iterable of OpenAI-like chunks for real-time streaming
|
|
807
785
|
const stream = await insforge.ai.chat.completions.create({
|
|
808
|
-
model:
|
|
809
|
-
messages: [{ role:
|
|
786
|
+
model: 'anthropic/claude-3.5-haiku',
|
|
787
|
+
messages: [{ role: 'user', content: 'Tell me a story' }],
|
|
810
788
|
stream: true,
|
|
811
789
|
});
|
|
812
790
|
|
|
@@ -835,8 +813,8 @@ Generate images using AI models.
|
|
|
835
813
|
```javascript
|
|
836
814
|
// Text-to-image
|
|
837
815
|
const image = await insforge.ai.images.generate({
|
|
838
|
-
model:
|
|
839
|
-
prompt:
|
|
816
|
+
model: 'google/gemini-3-pro-image-preview',
|
|
817
|
+
prompt: 'A serene landscape with mountains at sunset',
|
|
840
818
|
});
|
|
841
819
|
// Returns an OpenAI-like image object directly (not a { data, error } envelope):
|
|
842
820
|
// image.data[i].b64_json - base64-encoded image (no `data:` URI prefix)
|
|
@@ -846,9 +824,9 @@ const base64Png = image.data[0].b64_json;
|
|
|
846
824
|
|
|
847
825
|
// Image-to-image — pass source images as URLs or base64 data URIs
|
|
848
826
|
const edited = await insforge.ai.images.generate({
|
|
849
|
-
model:
|
|
850
|
-
prompt:
|
|
851
|
-
images: [{ url:
|
|
827
|
+
model: 'google/gemini-3-pro-image-preview',
|
|
828
|
+
prompt: 'Turn this into a watercolor painting',
|
|
829
|
+
images: [{ url: 'https://example.com/input.jpg' }],
|
|
852
830
|
});
|
|
853
831
|
```
|
|
854
832
|
|
|
@@ -866,8 +844,8 @@ Create embeddings for one or more text inputs.
|
|
|
866
844
|
|
|
867
845
|
```javascript
|
|
868
846
|
const embeddings = await insforge.ai.embeddings.create({
|
|
869
|
-
model:
|
|
870
|
-
input:
|
|
847
|
+
model: 'openai/text-embedding-3-small',
|
|
848
|
+
input: 'Hello world', // or string[] for batch input
|
|
871
849
|
});
|
|
872
850
|
// Returns an OpenAI-like embeddings object directly (not a { data, error } envelope):
|
|
873
851
|
// embeddings.data[i].embedding - the vector (number[]) for input i
|
|
@@ -886,27 +864,27 @@ console.log(embeddings.data[0].embedding);
|
|
|
886
864
|
### Complete AI Example
|
|
887
865
|
|
|
888
866
|
```javascript
|
|
889
|
-
import { createClient } from
|
|
867
|
+
import { createClient } from '@insforge/sdk';
|
|
890
868
|
|
|
891
869
|
const insforge = createClient({
|
|
892
|
-
baseUrl:
|
|
870
|
+
baseUrl: 'http://localhost:7130',
|
|
893
871
|
});
|
|
894
872
|
|
|
895
873
|
// Chat completion
|
|
896
874
|
const chat = await insforge.ai.chat.completions.create({
|
|
897
|
-
model:
|
|
898
|
-
messages: [{ role:
|
|
875
|
+
model: 'anthropic/claude-3.5-haiku',
|
|
876
|
+
messages: [{ role: 'user', content: 'What is the capital of France?' }],
|
|
899
877
|
});
|
|
900
878
|
console.log(chat.choices[0].message.content); // "The capital of France is Paris."
|
|
901
879
|
|
|
902
880
|
// Streaming chat
|
|
903
881
|
const stream = await insforge.ai.chat.completions.create({
|
|
904
|
-
model:
|
|
905
|
-
messages: [{ role:
|
|
882
|
+
model: 'anthropic/claude-3.5-haiku',
|
|
883
|
+
messages: [{ role: 'user', content: 'Write a haiku about coding' }],
|
|
906
884
|
stream: true,
|
|
907
885
|
});
|
|
908
886
|
|
|
909
|
-
let fullResponse =
|
|
887
|
+
let fullResponse = '';
|
|
910
888
|
for await (const chunk of stream) {
|
|
911
889
|
const delta = chunk.choices[0]?.delta?.content;
|
|
912
890
|
if (delta) {
|
|
@@ -917,15 +895,15 @@ for await (const chunk of stream) {
|
|
|
917
895
|
|
|
918
896
|
// Image generation
|
|
919
897
|
const image = await insforge.ai.images.generate({
|
|
920
|
-
model:
|
|
921
|
-
prompt:
|
|
898
|
+
model: 'google/gemini-3-pro-image-preview',
|
|
899
|
+
prompt: 'A futuristic city with flying cars',
|
|
922
900
|
});
|
|
923
901
|
const base64Png = image.data[0].b64_json; // base64-encoded image
|
|
924
902
|
|
|
925
903
|
// Embeddings
|
|
926
904
|
const embeddings = await insforge.ai.embeddings.create({
|
|
927
|
-
model:
|
|
928
|
-
input:
|
|
905
|
+
model: 'openai/text-embedding-3-small',
|
|
906
|
+
input: 'Vectorize this sentence',
|
|
929
907
|
});
|
|
930
908
|
console.log(embeddings.data[0].embedding); // number[]
|
|
931
909
|
```
|
|
@@ -943,7 +921,7 @@ import type {
|
|
|
943
921
|
ListObjectsResponseSchema,
|
|
944
922
|
PublicOAuthProvider,
|
|
945
923
|
GetPublicEmailAuthConfigResponse,
|
|
946
|
-
} from
|
|
924
|
+
} from '@insforge/shared-schemas';
|
|
947
925
|
|
|
948
926
|
// Database response type
|
|
949
927
|
interface DatabaseResponse<T> {
|