@insforge/sdk 1.4.3 → 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 CHANGED
@@ -33,11 +33,11 @@ yarn add @insforge/sdk
33
33
  ### Initialize the Client
34
34
 
35
35
  ```javascript
36
- import { createClient } from "@insforge/sdk";
36
+ import { createClient } from '@insforge/sdk';
37
37
 
38
38
  const insforge = createClient({
39
- baseUrl: "http://localhost:7130", // Your InsForge backend URL
40
- anonKey: "your-anon-key", // Optional public anon key
39
+ baseUrl: 'http://localhost:7130', // Your InsForge backend URL
40
+ anonKey: 'your-anon-key', // Optional public anon key
41
41
  });
42
42
  ```
43
43
 
@@ -46,10 +46,10 @@ const insforge = createClient({
46
46
  Use `createAdminClient()` only in trusted server code that needs project-admin privileges:
47
47
 
48
48
  ```typescript
49
- import { createAdminClient } from "@insforge/sdk";
49
+ import { createAdminClient } from '@insforge/sdk';
50
50
 
51
51
  const admin = createAdminClient({
52
- baseUrl: "http://localhost:7130",
52
+ baseUrl: 'http://localhost:7130',
53
53
  apiKey: process.env.INSFORGE_API_KEY!,
54
54
  });
55
55
  ```
@@ -62,7 +62,7 @@ In edge functions or other server code that receives a user's JWT, seed the clie
62
62
 
63
63
  ```javascript
64
64
  const insforge = createClient({
65
- baseUrl: "http://localhost:7130",
65
+ baseUrl: 'http://localhost:7130',
66
66
  accessToken: userJwt, // e.g. from the request's Authorization header
67
67
  });
68
68
  ```
@@ -74,22 +74,22 @@ All requests run as that user (RLS applies). The token is used as-is — the SDK
74
74
  ```javascript
75
75
  // Sign up a new user
76
76
  const { data, error } = await insforge.auth.signUp({
77
- email: "user@example.com",
78
- password: "securePassword123",
79
- name: "John Doe", // optional
80
- redirectTo: "http://localhost:3000/sign-in", // optional, recommended for link-based verification
77
+ email: 'user@example.com',
78
+ password: 'securePassword123',
79
+ name: 'John Doe', // optional
80
+ redirectTo: 'http://localhost:3000/sign-in', // optional, recommended for link-based verification
81
81
  });
82
82
 
83
83
  // Sign in with email/password
84
84
  const { data, error } = await insforge.auth.signInWithPassword({
85
- email: "user@example.com",
86
- password: "securePassword123",
85
+ email: 'user@example.com',
86
+ password: 'securePassword123',
87
87
  });
88
88
 
89
89
  // OAuth authentication (built-in or custom provider key)
90
- await insforge.auth.signInWithOAuth("google", {
91
- redirectTo: "http://localhost:3000/dashboard",
92
- additionalParams: { prompt: "select_account" },
90
+ await insforge.auth.signInWithOAuth('google', {
91
+ redirectTo: 'http://localhost:3000/dashboard',
92
+ additionalParams: { prompt: 'select_account' },
93
93
  });
94
94
  // additionalParams is for provider-specific hints only.
95
95
  // Do not pass client_id, scope, redirect_uri, code_challenge, state, or response_type;
@@ -99,13 +99,13 @@ await insforge.auth.signInWithOAuth("google", {
99
99
  const { data: currentUser } = await insforge.auth.getCurrentUser();
100
100
 
101
101
  // Get any user's profile by ID (public endpoint)
102
- const { data: profile, error } = await insforge.auth.getProfile("user-id-here");
102
+ const { data: profile, error } = await insforge.auth.getProfile('user-id-here');
103
103
 
104
104
  // Update current user's profile (requires authentication)
105
105
  const { data: updatedProfile, error } = await insforge.auth.setProfile({
106
- displayName: "John Doe",
107
- bio: "Software developer",
108
- avatarUrl: "https://example.com/avatar.jpg",
106
+ displayName: 'John Doe',
107
+ bio: 'Software developer',
108
+ avatarUrl: 'https://example.com/avatar.jpg',
109
109
  });
110
110
 
111
111
  // Sign out
@@ -117,31 +117,31 @@ await insforge.auth.signOut();
117
117
  ```javascript
118
118
  // Resend a verification email
119
119
  await insforge.auth.resendVerificationEmail({
120
- email: "user@example.com",
121
- redirectTo: "http://localhost:3000/sign-in", // optional, recommended for link-based verification
120
+ email: 'user@example.com',
121
+ redirectTo: 'http://localhost:3000/sign-in', // optional, recommended for link-based verification
122
122
  });
123
123
 
124
124
  // Verify email with a 6-digit code
125
125
  await insforge.auth.verifyEmail({
126
- email: "user@example.com",
127
- otp: "123456",
126
+ email: 'user@example.com',
127
+ otp: '123456',
128
128
  });
129
129
 
130
130
  // Send password reset email
131
131
  await insforge.auth.sendResetPasswordEmail({
132
- email: "user@example.com",
133
- redirectTo: "http://localhost:3000/reset-password", // optional, recommended for link-based reset
132
+ email: 'user@example.com',
133
+ redirectTo: 'http://localhost:3000/reset-password', // optional, recommended for link-based reset
134
134
  });
135
135
 
136
136
  // Code-based reset flow: exchange the code, then reset the password
137
137
  const { data: resetToken } = await insforge.auth.exchangeResetPasswordToken({
138
- email: "user@example.com",
139
- code: "123456",
138
+ email: 'user@example.com',
139
+ code: '123456',
140
140
  });
141
141
 
142
142
  if (resetToken) {
143
143
  await insforge.auth.resetPassword({
144
- newPassword: "newSecurePassword123",
144
+ newPassword: 'newSecurePassword123',
145
145
  otp: resetToken.token,
146
146
  });
147
147
  }
@@ -163,26 +163,20 @@ Those backend endpoints validate the token first, then redirect the browser to y
163
163
  ```javascript
164
164
  // Insert data
165
165
  const { data, error } = await insforge.database
166
- .from("posts")
167
- .insert([{ title: "My First Post", content: "Hello World!" }]);
166
+ .from('posts')
167
+ .insert([{ title: 'My First Post', content: 'Hello World!' }]);
168
168
 
169
169
  // Query data
170
- const { data, error } = await insforge.database
171
- .from("posts")
172
- .select("*")
173
- .eq("author_id", userId);
170
+ const { data, error } = await insforge.database.from('posts').select('*').eq('author_id', userId);
174
171
 
175
172
  // Update data
176
173
  const { data, error } = await insforge.database
177
- .from("posts")
178
- .update({ title: "Updated Title" })
179
- .eq("id", postId);
174
+ .from('posts')
175
+ .update({ title: 'Updated Title' })
176
+ .eq('id', postId);
180
177
 
181
178
  // Delete data
182
- const { data, error } = await insforge.database
183
- .from("posts")
184
- .delete()
185
- .eq("id", postId);
179
+ const { data, error } = await insforge.database.from('posts').delete().eq('id', postId);
186
180
  ```
187
181
 
188
182
  #### Selecting a schema
@@ -190,21 +184,18 @@ const { data, error } = await insforge.database
190
184
  Queries hit the `public` schema by default. Target a custom schema by chaining `.schema()` — the table name stays bare (it maps to PostgREST's `Accept-Profile`/`Content-Profile` header):
191
185
 
192
186
  ```javascript
193
- const { data } = await insforge.database
194
- .schema("analytics")
195
- .from("events")
196
- .select("*");
187
+ const { data } = await insforge.database.schema('analytics').from('events').select('*');
197
188
 
198
- await insforge.database.schema("analytics").rpc("rollup", { day: "2026-01-01" });
189
+ await insforge.database.schema('analytics').rpc('rollup', { day: '2026-01-01' });
199
190
  ```
200
191
 
201
192
  Or set a default schema for every query when creating the client:
202
193
 
203
194
  ```javascript
204
195
  const insforge = createClient({
205
- baseUrl: "...",
206
- anonKey: "...",
207
- db: { schema: "analytics" },
196
+ baseUrl: '...',
197
+ anonKey: '...',
198
+ db: { schema: 'analytics' },
208
199
  });
209
200
  ```
210
201
 
@@ -215,28 +206,24 @@ The schema must be exposed by the backend, and access is still gated by grants +
215
206
  ```javascript
216
207
  // Upload a file
217
208
  const file = document.querySelector('input[type="file"]').files[0];
218
- const { data, error } = await insforge.storage.from("avatars").upload(file);
209
+ const { data, error } = await insforge.storage.from('avatars').upload(file);
219
210
 
220
211
  // Download a file
221
- const { data, error } = await insforge.storage
222
- .from("avatars")
223
- .download("user-avatar.png");
212
+ const { data, error } = await insforge.storage.from('avatars').download('user-avatar.png');
224
213
 
225
214
  // Delete a file
226
- const { data, error } = await insforge.storage
227
- .from("avatars")
228
- .remove(["user-avatar.png"]);
215
+ const { data, error } = await insforge.storage.from('avatars').remove(['user-avatar.png']);
229
216
 
230
217
  // List files
231
- const { data, error } = await insforge.storage.from("avatars").list();
218
+ const { data, error } = await insforge.storage.from('avatars').list();
232
219
  ```
233
220
 
234
221
  ### Edge Functions
235
222
 
236
223
  ```javascript
237
224
  // Invoke an edge function
238
- const { data, error } = await insforge.functions.invoke("my-function", {
239
- body: { key: "value" },
225
+ const { data, error } = await insforge.functions.invoke('my-function', {
226
+ body: { key: 'value' },
240
227
  });
241
228
  ```
242
229
 
@@ -244,60 +231,58 @@ const { data, error } = await insforge.functions.invoke("my-function", {
244
231
 
245
232
  ```javascript
246
233
  // Create and redirect to a Stripe Checkout Session
247
- const { data, error } = await insforge.payments.stripe.createCheckoutSession(
248
- "test",
249
- {
250
- mode: "payment",
251
- lineItems: [{ priceId: "price_123", quantity: 1 }],
252
- successUrl: `${window.location.origin}/success`,
253
- cancelUrl: `${window.location.origin}/pricing`,
254
- idempotencyKey: "cart_123",
255
- },
256
- );
234
+ const { data, error } = await insforge.payments.stripe.createCheckoutSession('test', {
235
+ mode: 'payment',
236
+ lineItems: [{ priceId: 'price_123', quantity: 1 }],
237
+ successUrl: `${window.location.origin}/success`,
238
+ cancelUrl: `${window.location.origin}/pricing`,
239
+ idempotencyKey: 'cart_123',
240
+ });
257
241
 
258
242
  if (!error && data?.checkoutSession.url) {
259
243
  window.location.assign(data.checkoutSession.url);
260
244
  }
261
245
 
262
246
  // Create a subscription checkout for an app billing subject
263
- const { data: subscriptionCheckout } =
264
- await insforge.payments.stripe.createCheckoutSession("test", {
265
- mode: "subscription",
266
- subject: { type: "team", id: "team_123" },
267
- lineItems: [{ priceId: "price_monthly_123", quantity: 1 }],
247
+ const { data: subscriptionCheckout } = await insforge.payments.stripe.createCheckoutSession(
248
+ 'test',
249
+ {
250
+ mode: 'subscription',
251
+ subject: { type: 'team', id: 'team_123' },
252
+ lineItems: [{ priceId: 'price_monthly_123', quantity: 1 }],
268
253
  successUrl: `${window.location.origin}/billing/success`,
269
254
  cancelUrl: `${window.location.origin}/billing`,
270
- });
255
+ }
256
+ );
271
257
 
272
258
  if (subscriptionCheckout?.checkoutSession.url) {
273
259
  window.location.assign(subscriptionCheckout.checkoutSession.url);
274
260
  }
275
261
 
276
262
  // Let an authenticated customer manage their subscription in Stripe Billing Portal
277
- const { data: portal } =
278
- await insforge.payments.stripe.createCustomerPortalSession("test", {
279
- subject: { type: "team", id: "team_123" },
280
- returnUrl: `${window.location.origin}/billing`,
281
- });
263
+ const { data: portal } = await insforge.payments.stripe.createCustomerPortalSession('test', {
264
+ subject: { type: 'team', id: 'team_123' },
265
+ returnUrl: `${window.location.origin}/billing`,
266
+ });
282
267
 
283
268
  if (portal?.customerPortalSession.url) {
284
269
  window.location.assign(portal.customerPortalSession.url);
285
270
  }
286
271
 
287
272
  // Create a Razorpay order, then pass checkoutOptions to Razorpay Checkout.js
288
- const { data: order } = await insforge.payments.razorpay.createOrder("test", {
273
+ const { data: order } = await insforge.payments.razorpay.createOrder('test', {
289
274
  amount: 200000,
290
- currency: "INR",
291
- subject: { type: "team", id: "team_123" },
292
- customerEmail: "ada@example.com",
293
- notes: { order_id: "order_123" },
275
+ currency: 'INR',
276
+ subject: { type: 'team', id: 'team_123' },
277
+ customerEmail: 'ada@example.com',
278
+ notes: { order_id: 'order_123' },
294
279
  });
295
280
 
296
281
  if (order) {
297
282
  const checkout = new Razorpay({
298
283
  ...order.checkoutOptions,
299
284
  handler: async (response) => {
300
- await insforge.payments.razorpay.verifyOrder("test", {
285
+ await insforge.payments.razorpay.verifyOrder('test', {
301
286
  orderId: response.razorpay_order_id,
302
287
  paymentId: response.razorpay_payment_id,
303
288
  signature: response.razorpay_signature,
@@ -308,13 +293,12 @@ if (order) {
308
293
  }
309
294
 
310
295
  // Create a Razorpay subscription checkout for an app billing subject
311
- const { data: subscription } =
312
- await insforge.payments.razorpay.createSubscription("test", {
313
- planId: "plan_123",
314
- totalCount: 12,
315
- subject: { type: "team", id: "team_123" },
316
- notes: { order_id: "order_123" },
317
- });
296
+ const { data: subscription } = await insforge.payments.razorpay.createSubscription('test', {
297
+ planId: 'plan_123',
298
+ totalCount: 12,
299
+ subject: { type: 'team', id: 'team_123' },
300
+ notes: { order_id: 'order_123' },
301
+ });
318
302
  ```
319
303
 
320
304
  ### AI Integration
@@ -324,32 +308,32 @@ AI methods return an OpenAI-like response object directly (not the `{ data, erro
324
308
  ```javascript
325
309
  // Chat completion
326
310
  const completion = await insforge.ai.chat.completions.create({
327
- model: "anthropic/claude-3.5-haiku",
328
- messages: [{ role: "user", content: "Write a hello world program" }],
311
+ model: 'anthropic/claude-3.5-haiku',
312
+ messages: [{ role: 'user', content: 'Write a hello world program' }],
329
313
  });
330
314
  console.log(completion.choices[0].message.content);
331
315
 
332
316
  // Streaming chat — returns an async iterable of chunks
333
317
  const stream = await insforge.ai.chat.completions.create({
334
- model: "anthropic/claude-3.5-haiku",
335
- messages: [{ role: "user", content: "Tell me a story" }],
318
+ model: 'anthropic/claude-3.5-haiku',
319
+ messages: [{ role: 'user', content: 'Tell me a story' }],
336
320
  stream: true,
337
321
  });
338
322
  for await (const chunk of stream) {
339
- process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
323
+ process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
340
324
  }
341
325
 
342
326
  // Generate an image — returns base64-encoded image data
343
327
  const image = await insforge.ai.images.generate({
344
- model: "google/gemini-3-pro-image-preview",
345
- prompt: "A sunset over mountains",
328
+ model: 'google/gemini-3-pro-image-preview',
329
+ prompt: 'A sunset over mountains',
346
330
  });
347
331
  const base64Png = image.data[0].b64_json;
348
332
 
349
333
  // Create embeddings
350
334
  const embeddings = await insforge.ai.embeddings.create({
351
- model: "openai/text-embedding-3-small",
352
- input: "Hello world",
335
+ model: 'openai/text-embedding-3-small',
336
+ input: 'Hello world',
353
337
  });
354
338
  console.log(embeddings.data[0].embedding); // number[]
355
339
  ```
@@ -367,8 +351,8 @@ The SDK supports the following configuration options:
367
351
 
368
352
  ```javascript
369
353
  const insforge = createClient({
370
- baseUrl: "http://localhost:7130", // Your InsForge backend URL
371
- anonKey: "your-anon-key", // Optional
354
+ baseUrl: 'http://localhost:7130', // Your InsForge backend URL
355
+ anonKey: 'your-anon-key', // Optional
372
356
  });
373
357
  ```
374
358
 
@@ -386,7 +370,7 @@ By default, the SSR helpers use:
386
370
 
387
371
  ```typescript
388
372
  // app/lib/insforge/client.ts
389
- import { createBrowserClient } from "@insforge/sdk/ssr";
373
+ import { createBrowserClient } from '@insforge/sdk/ssr';
390
374
 
391
375
  export const insforge = createBrowserClient();
392
376
  ```
@@ -398,8 +382,8 @@ server so the app can write server-owned auth cookies.
398
382
 
399
383
  ```typescript
400
384
  // app/lib/insforge/server.ts
401
- import { cookies } from "next/headers";
402
- import { createServerClient } from "@insforge/sdk/ssr";
385
+ import { cookies } from 'next/headers';
386
+ import { createServerClient } from '@insforge/sdk/ssr';
403
387
 
404
388
  export async function createInsForgeServerClient() {
405
389
  return createServerClient({ cookies: await cookies() });
@@ -408,7 +392,7 @@ export async function createInsForgeServerClient() {
408
392
 
409
393
  ```typescript
410
394
  // app/api/auth/refresh/route.ts
411
- import { createRefreshAuthRouter } from "@insforge/sdk/ssr";
395
+ import { createRefreshAuthRouter } from '@insforge/sdk/ssr';
412
396
 
413
397
  export const { POST } = createRefreshAuthRouter();
414
398
  ```
@@ -420,17 +404,17 @@ so access and refresh tokens stay server-owned.
420
404
 
421
405
  ```typescript
422
406
  // app/actions.ts
423
- "use server";
407
+ 'use server';
424
408
 
425
- import { cookies } from "next/headers";
426
- import { createAuthActions } from "@insforge/sdk/ssr";
409
+ import { cookies } from 'next/headers';
410
+ import { createAuthActions } from '@insforge/sdk/ssr';
427
411
 
428
412
  export async function signIn(formData: FormData) {
429
413
  const auth = createAuthActions({ cookies: await cookies() });
430
414
 
431
415
  const { data, error } = await auth.signInWithPassword({
432
- email: String(formData.get("email")),
433
- password: String(formData.get("password")),
416
+ email: String(formData.get('email')),
417
+ password: String(formData.get('password')),
434
418
  });
435
419
 
436
420
  return { user: data?.user ?? null, error };
@@ -443,32 +427,29 @@ verifier in an httpOnly app cookie and exchange the callback code with
443
427
 
444
428
  ```typescript
445
429
  // app/actions.ts
446
- "use server";
430
+ 'use server';
447
431
 
448
- import { cookies } from "next/headers";
449
- import { redirect } from "next/navigation";
450
- import { createAuthActions } from "@insforge/sdk/ssr";
432
+ import { cookies } from 'next/headers';
433
+ import { redirect } from 'next/navigation';
434
+ import { createAuthActions } from '@insforge/sdk/ssr';
451
435
 
452
436
  export async function signInWithGoogle() {
453
437
  const cookieStore = await cookies();
454
438
  const auth = createAuthActions({ cookies: cookieStore });
455
- const { data, error } = await auth.signInWithOAuth("google", {
456
- redirectTo: new URL(
457
- "/api/auth/callback",
458
- process.env.NEXT_PUBLIC_APP_URL
459
- ).toString(),
439
+ const { data, error } = await auth.signInWithOAuth('google', {
440
+ redirectTo: new URL('/api/auth/callback', process.env.NEXT_PUBLIC_APP_URL).toString(),
460
441
  skipBrowserRedirect: true,
461
442
  });
462
443
 
463
444
  if (error || !data.url || !data.codeVerifier) {
464
- throw new Error(error?.message ?? "OAuth init failed");
445
+ throw new Error(error?.message ?? 'OAuth init failed');
465
446
  }
466
447
 
467
- cookieStore.set("insforge_code_verifier", data.codeVerifier, {
448
+ cookieStore.set('insforge_code_verifier', data.codeVerifier, {
468
449
  httpOnly: true,
469
- secure: process.env.NODE_ENV === "production",
470
- sameSite: "lax",
471
- path: "/",
450
+ secure: process.env.NODE_ENV === 'production',
451
+ sameSite: 'lax',
452
+ path: '/',
472
453
  maxAge: 600,
473
454
  });
474
455
 
@@ -478,28 +459,28 @@ export async function signInWithGoogle() {
478
459
 
479
460
  ```typescript
480
461
  // app/api/auth/callback/route.ts
481
- import { cookies } from "next/headers";
482
- import { NextResponse, type NextRequest } from "next/server";
483
- import { createAuthActions } from "@insforge/sdk/ssr";
462
+ import { cookies } from 'next/headers';
463
+ import { NextResponse, type NextRequest } from 'next/server';
464
+ import { createAuthActions } from '@insforge/sdk/ssr';
484
465
 
485
466
  export async function GET(request: NextRequest) {
486
- const code = request.nextUrl.searchParams.get("insforge_code");
487
- const verifier = (await cookies()).get("insforge_code_verifier")?.value;
467
+ const code = request.nextUrl.searchParams.get('insforge_code');
468
+ const verifier = (await cookies()).get('insforge_code_verifier')?.value;
488
469
  if (!code || !verifier) {
489
- return NextResponse.redirect(new URL("/login?error=oauth", request.url));
470
+ return NextResponse.redirect(new URL('/login?error=oauth', request.url));
490
471
  }
491
472
 
492
- const response = NextResponse.redirect(new URL("/dashboard", request.url));
473
+ const response = NextResponse.redirect(new URL('/dashboard', request.url));
493
474
  const auth = createAuthActions({
494
475
  requestCookies: request.cookies,
495
476
  responseCookies: response.cookies,
496
477
  });
497
478
  const { error } = await auth.exchangeOAuthCode(code, verifier);
498
479
  if (error) {
499
- return NextResponse.redirect(new URL("/login?error=oauth", request.url));
480
+ return NextResponse.redirect(new URL('/login?error=oauth', request.url));
500
481
  }
501
482
 
502
- response.cookies.delete("insforge_code_verifier");
483
+ response.cookies.delete('insforge_code_verifier');
503
484
  return response;
504
485
  }
505
486
  ```
@@ -513,8 +494,8 @@ response cookies for writing the next session:
513
494
 
514
495
  ```typescript
515
496
  // app/api/auth/sign-out/route.ts
516
- import { NextResponse, type NextRequest } from "next/server";
517
- import { createAuthActions } from "@insforge/sdk/ssr";
497
+ import { NextResponse, type NextRequest } from 'next/server';
498
+ import { createAuthActions } from '@insforge/sdk/ssr';
518
499
 
519
500
  export async function POST(request: NextRequest) {
520
501
  const response = NextResponse.json({ ok: true });
@@ -538,7 +519,7 @@ export async function POST(request: NextRequest) {
538
519
  If your refresh route needs custom side effects:
539
520
 
540
521
  ```typescript
541
- import { refreshAuth } from "@insforge/sdk/ssr";
522
+ import { refreshAuth } from '@insforge/sdk/ssr';
542
523
 
543
524
  export async function POST(request: Request) {
544
525
  const result = await refreshAuth({ request });
@@ -551,8 +532,8 @@ For Next.js Proxy/Middleware, refresh before Server Components render:
551
532
 
552
533
  ```typescript
553
534
  // proxy.ts on Next.js 16+, middleware.ts on Next.js 15 and earlier
554
- import { NextResponse, type NextRequest } from "next/server";
555
- import { updateSession } from "@insforge/sdk/ssr/middleware";
535
+ import { NextResponse, type NextRequest } from 'next/server';
536
+ import { updateSession } from '@insforge/sdk/ssr/middleware';
556
537
 
557
538
  export async function proxy(request: NextRequest) {
558
539
  const response = NextResponse.next({ request });
@@ -574,10 +555,10 @@ the session refresh helpers and avoids bundling the full SDK client.
574
555
  The SDK is written in TypeScript and provides full type definitions:
575
556
 
576
557
  ```typescript
577
- import { createClient, InsForgeClient } from "@insforge/sdk";
558
+ import { createClient, InsForgeClient } from '@insforge/sdk';
578
559
 
579
560
  const insforge: InsForgeClient = createClient({
580
- baseUrl: "http://localhost:7130",
561
+ baseUrl: 'http://localhost:7130',
581
562
  });
582
563
 
583
564
  // Type-safe API calls