@insforge/sdk 0.0.19 → 0.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -441,106 +441,6 @@ declare class Storage {
441
441
  from(bucketName: string): StorageBucket;
442
442
  }
443
443
 
444
- /**
445
- * AI Module for Insforge SDK
446
- * Wrapper for AI endpoints that follows OpenAI-like patterns
447
- *
448
- * The backend handles all the complexity of different AI providers
449
- * and returns a unified format. This SDK just calls the endpoints.
450
- */
451
-
452
- declare class AI {
453
- private http;
454
- readonly chat: Chat;
455
- readonly images: Images;
456
- constructor(http: HttpClient);
457
- }
458
- declare class Chat {
459
- readonly completions: ChatCompletions;
460
- constructor(http: HttpClient);
461
- }
462
- declare class ChatCompletions {
463
- private http;
464
- constructor(http: HttpClient);
465
- /**
466
- * Create a chat completion
467
- *
468
- * @example
469
- * ```typescript
470
- * // Non-streaming
471
- * const response = await client.ai.chat.completions.create({
472
- * model: 'gpt-4',
473
- * messages: [{ role: 'user', content: 'Hello!' }]
474
- * });
475
- * console.log(response.response);
476
- *
477
- * // Streaming - returns async iterable
478
- * const stream = await client.ai.chat.completions.create({
479
- * model: 'gpt-4',
480
- * messages: [{ role: 'user', content: 'Tell me a story' }],
481
- * stream: true
482
- * });
483
- *
484
- * for await (const event of stream) {
485
- * if (event.chunk) {
486
- * process.stdout.write(event.chunk);
487
- * }
488
- * if (event.done) {
489
- * console.log('Stream complete!');
490
- * }
491
- * }
492
- * ```
493
- */
494
- create(params: {
495
- model: string;
496
- messages?: Array<{
497
- role: 'user' | 'assistant' | 'system';
498
- content: string;
499
- }>;
500
- message?: string;
501
- temperature?: number;
502
- maxTokens?: number;
503
- topP?: number;
504
- systemPrompt?: string;
505
- stream?: boolean;
506
- }): Promise<any>;
507
- /**
508
- * Parse SSE stream into async iterable of parsed events
509
- * Users don't need to handle SSE parsing themselves
510
- */
511
- private parseSSEStream;
512
- }
513
- declare class Images {
514
- private http;
515
- constructor(http: HttpClient);
516
- /**
517
- * Generate images
518
- *
519
- * @example
520
- * ```typescript
521
- * const response = await client.ai.images.generate({
522
- * model: 'dall-e-3',
523
- * prompt: 'A sunset over mountains',
524
- * numImages: 1,
525
- * size: '1024x1024'
526
- * });
527
- * console.log(response.images[0].url);
528
- * ```
529
- */
530
- generate(params: {
531
- model: string;
532
- prompt: string;
533
- negativePrompt?: string;
534
- width?: number;
535
- height?: number;
536
- numImages?: number;
537
- quality?: 'standard' | 'hd';
538
- style?: 'vivid' | 'natural';
539
- responseFormat?: 'url' | 'b64_json';
540
- size?: string;
541
- }): Promise<unknown>;
542
- }
543
-
544
444
  /**
545
445
  * Main InsForge SDK Client
546
446
  *
@@ -580,7 +480,6 @@ declare class InsForgeClient {
580
480
  readonly auth: Auth;
581
481
  readonly database: Database;
582
482
  readonly storage: Storage;
583
- readonly ai: AI;
584
483
  constructor(config?: InsForgeConfig);
585
484
  /**
586
485
  * Set a custom API key for authentication
@@ -614,4 +513,4 @@ declare class InsForgeClient {
614
513
 
615
514
  declare function createClient(config: InsForgeConfig): InsForgeClient;
616
515
 
617
- export { AI, type ApiError, Auth, type AuthSession, type InsForgeConfig as ClientOptions, Database, type DatabaseResponse, HttpClient, InsForgeClient, type InsForgeConfig, InsForgeError, QueryBuilder, Storage, StorageBucket, type StorageResponse, TokenManager, type TokenStorage, createClient, InsForgeClient as default };
516
+ export { type ApiError, Auth, type AuthSession, type InsForgeConfig as ClientOptions, Database, type DatabaseResponse, HttpClient, InsForgeClient, type InsForgeConfig, InsForgeError, QueryBuilder, Storage, StorageBucket, type StorageResponse, TokenManager, type TokenStorage, createClient, InsForgeClient as default };
package/dist/index.d.ts CHANGED
@@ -441,106 +441,6 @@ declare class Storage {
441
441
  from(bucketName: string): StorageBucket;
442
442
  }
443
443
 
444
- /**
445
- * AI Module for Insforge SDK
446
- * Wrapper for AI endpoints that follows OpenAI-like patterns
447
- *
448
- * The backend handles all the complexity of different AI providers
449
- * and returns a unified format. This SDK just calls the endpoints.
450
- */
451
-
452
- declare class AI {
453
- private http;
454
- readonly chat: Chat;
455
- readonly images: Images;
456
- constructor(http: HttpClient);
457
- }
458
- declare class Chat {
459
- readonly completions: ChatCompletions;
460
- constructor(http: HttpClient);
461
- }
462
- declare class ChatCompletions {
463
- private http;
464
- constructor(http: HttpClient);
465
- /**
466
- * Create a chat completion
467
- *
468
- * @example
469
- * ```typescript
470
- * // Non-streaming
471
- * const response = await client.ai.chat.completions.create({
472
- * model: 'gpt-4',
473
- * messages: [{ role: 'user', content: 'Hello!' }]
474
- * });
475
- * console.log(response.response);
476
- *
477
- * // Streaming - returns async iterable
478
- * const stream = await client.ai.chat.completions.create({
479
- * model: 'gpt-4',
480
- * messages: [{ role: 'user', content: 'Tell me a story' }],
481
- * stream: true
482
- * });
483
- *
484
- * for await (const event of stream) {
485
- * if (event.chunk) {
486
- * process.stdout.write(event.chunk);
487
- * }
488
- * if (event.done) {
489
- * console.log('Stream complete!');
490
- * }
491
- * }
492
- * ```
493
- */
494
- create(params: {
495
- model: string;
496
- messages?: Array<{
497
- role: 'user' | 'assistant' | 'system';
498
- content: string;
499
- }>;
500
- message?: string;
501
- temperature?: number;
502
- maxTokens?: number;
503
- topP?: number;
504
- systemPrompt?: string;
505
- stream?: boolean;
506
- }): Promise<any>;
507
- /**
508
- * Parse SSE stream into async iterable of parsed events
509
- * Users don't need to handle SSE parsing themselves
510
- */
511
- private parseSSEStream;
512
- }
513
- declare class Images {
514
- private http;
515
- constructor(http: HttpClient);
516
- /**
517
- * Generate images
518
- *
519
- * @example
520
- * ```typescript
521
- * const response = await client.ai.images.generate({
522
- * model: 'dall-e-3',
523
- * prompt: 'A sunset over mountains',
524
- * numImages: 1,
525
- * size: '1024x1024'
526
- * });
527
- * console.log(response.images[0].url);
528
- * ```
529
- */
530
- generate(params: {
531
- model: string;
532
- prompt: string;
533
- negativePrompt?: string;
534
- width?: number;
535
- height?: number;
536
- numImages?: number;
537
- quality?: 'standard' | 'hd';
538
- style?: 'vivid' | 'natural';
539
- responseFormat?: 'url' | 'b64_json';
540
- size?: string;
541
- }): Promise<unknown>;
542
- }
543
-
544
444
  /**
545
445
  * Main InsForge SDK Client
546
446
  *
@@ -580,7 +480,6 @@ declare class InsForgeClient {
580
480
  readonly auth: Auth;
581
481
  readonly database: Database;
582
482
  readonly storage: Storage;
583
- readonly ai: AI;
584
483
  constructor(config?: InsForgeConfig);
585
484
  /**
586
485
  * Set a custom API key for authentication
@@ -614,4 +513,4 @@ declare class InsForgeClient {
614
513
 
615
514
  declare function createClient(config: InsForgeConfig): InsForgeClient;
616
515
 
617
- export { AI, type ApiError, Auth, type AuthSession, type InsForgeConfig as ClientOptions, Database, type DatabaseResponse, HttpClient, InsForgeClient, type InsForgeConfig, InsForgeError, QueryBuilder, Storage, StorageBucket, type StorageResponse, TokenManager, type TokenStorage, createClient, InsForgeClient as default };
516
+ export { type ApiError, Auth, type AuthSession, type InsForgeConfig as ClientOptions, Database, type DatabaseResponse, HttpClient, InsForgeClient, type InsForgeConfig, InsForgeError, QueryBuilder, Storage, StorageBucket, type StorageResponse, TokenManager, type TokenStorage, createClient, InsForgeClient as default };
package/dist/index.js CHANGED
@@ -20,7 +20,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- AI: () => AI,
24
23
  Auth: () => Auth,
25
24
  Database: () => Database,
26
25
  HttpClient: () => HttpClient,
@@ -76,7 +75,8 @@ var HttpClient = class {
76
75
  if (params) {
77
76
  Object.entries(params).forEach(([key, value]) => {
78
77
  if (key === "select") {
79
- const normalizedValue = value.replace(/\s+/g, " ").trim();
78
+ let normalizedValue = value.replace(/\s+/g, " ").trim();
79
+ normalizedValue = normalizedValue.replace(/\s*\(\s*/g, "(").replace(/\s*\)\s*/g, ")").replace(/\(\s+/g, "(").replace(/\s+\)/g, ")").replace(/,\s+(?=[^()]*\))/g, ",");
80
80
  url.searchParams.append(key, normalizedValue);
81
81
  } else {
82
82
  url.searchParams.append(key, value);
@@ -936,133 +936,6 @@ var Storage = class {
936
936
  }
937
937
  };
938
938
 
939
- // src/modules/ai.ts
940
- var AI = class {
941
- constructor(http) {
942
- this.http = http;
943
- this.chat = new Chat(http);
944
- this.images = new Images(http);
945
- }
946
- };
947
- var Chat = class {
948
- constructor(http) {
949
- this.completions = new ChatCompletions(http);
950
- }
951
- };
952
- var ChatCompletions = class {
953
- constructor(http) {
954
- this.http = http;
955
- }
956
- /**
957
- * Create a chat completion
958
- *
959
- * @example
960
- * ```typescript
961
- * // Non-streaming
962
- * const response = await client.ai.chat.completions.create({
963
- * model: 'gpt-4',
964
- * messages: [{ role: 'user', content: 'Hello!' }]
965
- * });
966
- * console.log(response.response);
967
- *
968
- * // Streaming - returns async iterable
969
- * const stream = await client.ai.chat.completions.create({
970
- * model: 'gpt-4',
971
- * messages: [{ role: 'user', content: 'Tell me a story' }],
972
- * stream: true
973
- * });
974
- *
975
- * for await (const event of stream) {
976
- * if (event.chunk) {
977
- * process.stdout.write(event.chunk);
978
- * }
979
- * if (event.done) {
980
- * console.log('Stream complete!');
981
- * }
982
- * }
983
- * ```
984
- */
985
- async create(params) {
986
- if (params.stream) {
987
- const headers = this.http.getHeaders();
988
- headers["Content-Type"] = "application/json";
989
- const response = await this.http.fetch(
990
- `${this.http.baseUrl}/api/ai/chat`,
991
- {
992
- method: "POST",
993
- headers,
994
- body: JSON.stringify(params)
995
- }
996
- );
997
- if (!response.ok) {
998
- const error = await response.json();
999
- throw new Error(error.error || "Stream request failed");
1000
- }
1001
- return this.parseSSEStream(response);
1002
- }
1003
- return this.http.post("/api/ai/chat", params);
1004
- }
1005
- /**
1006
- * Parse SSE stream into async iterable of parsed events
1007
- * Users don't need to handle SSE parsing themselves
1008
- */
1009
- async *parseSSEStream(response) {
1010
- const reader = response.body.getReader();
1011
- const decoder = new TextDecoder();
1012
- let buffer = "";
1013
- try {
1014
- while (true) {
1015
- const { done, value } = await reader.read();
1016
- if (done) break;
1017
- buffer += decoder.decode(value, { stream: true });
1018
- const lines = buffer.split("\n");
1019
- buffer = lines.pop() || "";
1020
- for (const line of lines) {
1021
- if (line.startsWith("data: ")) {
1022
- const dataStr = line.slice(6).trim();
1023
- if (dataStr) {
1024
- try {
1025
- const data = JSON.parse(dataStr);
1026
- yield data;
1027
- if (data.done) {
1028
- reader.releaseLock();
1029
- return;
1030
- }
1031
- } catch (e) {
1032
- console.warn("Failed to parse SSE data:", dataStr);
1033
- }
1034
- }
1035
- }
1036
- }
1037
- }
1038
- } finally {
1039
- reader.releaseLock();
1040
- }
1041
- }
1042
- };
1043
- var Images = class {
1044
- constructor(http) {
1045
- this.http = http;
1046
- }
1047
- /**
1048
- * Generate images
1049
- *
1050
- * @example
1051
- * ```typescript
1052
- * const response = await client.ai.images.generate({
1053
- * model: 'dall-e-3',
1054
- * prompt: 'A sunset over mountains',
1055
- * numImages: 1,
1056
- * size: '1024x1024'
1057
- * });
1058
- * console.log(response.images[0].url);
1059
- * ```
1060
- */
1061
- async generate(params) {
1062
- return this.http.post("/api/ai/image/generation", params);
1063
- }
1064
- };
1065
-
1066
939
  // src/client.ts
1067
940
  var InsForgeClient = class {
1068
941
  constructor(config = {}) {
@@ -1074,7 +947,6 @@ var InsForgeClient = class {
1074
947
  );
1075
948
  this.database = new Database(this.http);
1076
949
  this.storage = new Storage(this.http);
1077
- this.ai = new AI(this.http);
1078
950
  }
1079
951
  /**
1080
952
  * Set a custom API key for authentication
@@ -1119,7 +991,6 @@ function createClient(config) {
1119
991
  var index_default = InsForgeClient;
1120
992
  // Annotate the CommonJS export names for ESM import in node:
1121
993
  0 && (module.exports = {
1122
- AI,
1123
994
  Auth,
1124
995
  Database,
1125
996
  HttpClient,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/lib/http-client.ts","../src/lib/token-manager.ts","../src/modules/database.ts","../src/modules/auth.ts","../src/modules/storage.ts","../src/modules/ai.ts","../src/client.ts"],"sourcesContent":["/**\n * @insforge/sdk - TypeScript SDK for InsForge Backend-as-a-Service\n * \n * @packageDocumentation\n */\n\n// Main client\nexport { InsForgeClient } from './client';\n\n// Types\nexport type {\n InsForgeConfig,\n InsForgeConfig as ClientOptions, // Alias for compatibility\n TokenStorage,\n AuthSession,\n ApiError,\n} from './types';\n\nexport { InsForgeError } from './types';\n\n// Re-export shared schemas that SDK users will need\nexport type {\n UserSchema,\n CreateUserRequest,\n CreateSessionRequest,\n AuthErrorResponse,\n} from '@insforge/shared-schemas';\n\n// Re-export auth module for advanced usage\nexport { Auth } from './modules/auth';\n\n// Re-export database module and types\nexport { Database, QueryBuilder } from './modules/database';\nexport type { DatabaseResponse } from './modules/database';\n\n// Re-export storage module and types\nexport { Storage, StorageBucket } from './modules/storage';\nexport type { StorageResponse } from './modules/storage';\n\n// Re-export AI module\nexport { AI } from './modules/ai';\n\n// Re-export utilities for advanced usage\nexport { HttpClient } from './lib/http-client';\nexport { TokenManager } from './lib/token-manager';\n\n// Factory function for creating clients (Supabase-style)\nimport { InsForgeClient } from './client';\nimport { InsForgeConfig } from './types';\n\nexport function createClient(config: InsForgeConfig): InsForgeClient {\n return new InsForgeClient(config);\n}\n\n// Default export for convenience\nexport default InsForgeClient;","/**\n * InsForge SDK Types - only SDK-specific types here\n * Use @insforge/shared-schemas directly for API types\n */\n\nimport type { UserSchema } from '@insforge/shared-schemas';\n\nexport interface InsForgeConfig {\n /**\n * The base URL of the InsForge backend API\n * @default \"http://localhost:7130\"\n */\n baseUrl?: string;\n\n /**\n * API key (optional)\n * Can be used for server-side operations or specific use cases\n */\n apiKey?: string;\n\n /**\n * Custom fetch implementation (useful for Node.js environments)\n */\n fetch?: typeof fetch;\n\n /**\n * Storage adapter for persisting tokens\n */\n storage?: TokenStorage;\n\n /**\n * Whether to automatically refresh tokens before they expire\n * @default true\n */\n autoRefreshToken?: boolean;\n\n /**\n * Whether to persist session in storage\n * @default true\n */\n persistSession?: boolean;\n\n /**\n * Custom headers to include with every request\n */\n headers?: Record<string, string>;\n}\n\nexport interface TokenStorage {\n getItem(key: string): string | null | Promise<string | null>;\n setItem(key: string, value: string): void | Promise<void>;\n removeItem(key: string): void | Promise<void>;\n}\n\nexport interface AuthSession {\n user: UserSchema;\n accessToken: string;\n expiresAt?: Date;\n}\n\nexport interface ApiError {\n error: string;\n message: string;\n statusCode: number;\n nextActions?: string;\n}\n\nexport class InsForgeError extends Error {\n public statusCode: number;\n public error: string;\n public nextActions?: string;\n\n constructor(message: string, statusCode: number, error: string, nextActions?: string) {\n super(message);\n this.name = 'InsForgeError';\n this.statusCode = statusCode;\n this.error = error;\n this.nextActions = nextActions;\n }\n\n static fromApiError(apiError: ApiError): InsForgeError {\n return new InsForgeError(\n apiError.message,\n apiError.statusCode,\n apiError.error,\n apiError.nextActions\n );\n }\n}","import { InsForgeConfig, ApiError, InsForgeError } from '../types';\n\nexport interface RequestOptions extends RequestInit {\n params?: Record<string, string>;\n}\n\nexport class HttpClient {\n public readonly baseUrl: string;\n public readonly fetch: typeof fetch;\n private defaultHeaders: Record<string, string>;\n\n constructor(config: InsForgeConfig) {\n this.baseUrl = config.baseUrl || 'http://localhost:7130';\n // Properly bind fetch to maintain its context\n this.fetch = config.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined as any);\n this.defaultHeaders = {\n ...config.headers,\n };\n \n // Add API key if provided\n if (config.apiKey) {\n this.defaultHeaders['Authorization'] = `Bearer ${config.apiKey}`;\n }\n\n if (!this.fetch) {\n throw new Error(\n 'Fetch is not available. Please provide a fetch implementation in the config.'\n );\n }\n }\n\n private buildUrl(path: string, params?: Record<string, string>): string {\n const url = new URL(path, this.baseUrl);\n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n // For select parameter, preserve the exact formatting by normalizing whitespace\n // This ensures PostgREST relationship queries work correctly\n if (key === 'select') {\n // Normalize multiline select strings: remove extra whitespace but preserve structure\n const normalizedValue = value.replace(/\\s+/g, ' ').trim();\n url.searchParams.append(key, normalizedValue);\n } else {\n url.searchParams.append(key, value);\n }\n });\n }\n return url.toString();\n }\n\n async request<T>(\n method: string,\n path: string,\n options: RequestOptions = {}\n ): Promise<T> {\n const { params, headers = {}, body, ...fetchOptions } = options;\n \n const url = this.buildUrl(path, params);\n \n const requestHeaders: Record<string, string> = {\n ...this.defaultHeaders,\n };\n \n // Handle body serialization\n let processedBody: any;\n if (body !== undefined) {\n // Check if body is FormData (for file uploads)\n if (typeof FormData !== 'undefined' && body instanceof FormData) {\n // Don't set Content-Type for FormData, let browser set it with boundary\n processedBody = body;\n } else {\n // JSON body\n if (method !== 'GET') {\n requestHeaders['Content-Type'] = 'application/json;charset=UTF-8';\n }\n processedBody = JSON.stringify(body);\n }\n }\n \n Object.assign(requestHeaders, headers);\n \n const response = await this.fetch(url, {\n method,\n headers: requestHeaders,\n body: processedBody,\n ...fetchOptions,\n });\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n // Try to parse JSON response\n let data: any;\n const contentType = response.headers.get('content-type');\n // Check for any JSON content type (including PostgREST's vnd.pgrst.object+json)\n if (contentType?.includes('json')) {\n data = await response.json();\n } else {\n // For non-JSON responses, return text\n data = await response.text();\n }\n\n // Handle errors\n if (!response.ok) {\n if (data && typeof data === 'object' && 'error' in data) {\n throw InsForgeError.fromApiError(data as ApiError);\n }\n throw new InsForgeError(\n `Request failed: ${response.statusText}`,\n response.status,\n 'REQUEST_FAILED'\n );\n }\n\n return data as T;\n }\n\n get<T>(path: string, options?: RequestOptions): Promise<T> {\n return this.request<T>('GET', path, options);\n }\n\n post<T>(path: string, body?: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('POST', path, { ...options, body });\n }\n\n put<T>(path: string, body?: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('PUT', path, { ...options, body });\n }\n\n patch<T>(path: string, body?: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('PATCH', path, { ...options, body });\n }\n\n delete<T>(path: string, options?: RequestOptions): Promise<T> {\n return this.request<T>('DELETE', path, options);\n }\n\n setAuthToken(token: string | null) {\n if (token) {\n this.defaultHeaders['Authorization'] = `Bearer ${token}`;\n } else {\n delete this.defaultHeaders['Authorization'];\n }\n }\n\n getHeaders(): Record<string, string> {\n return { ...this.defaultHeaders };\n }\n}","import { TokenStorage, AuthSession } from '../types';\n\nconst TOKEN_KEY = 'insforge-auth-token';\nconst USER_KEY = 'insforge-auth-user';\n\nexport class TokenManager {\n private storage: TokenStorage;\n\n constructor(storage?: TokenStorage) {\n if (storage) {\n // Use provided storage\n this.storage = storage;\n } else if (typeof window !== 'undefined' && window.localStorage) {\n // Browser: use localStorage\n this.storage = window.localStorage;\n } else {\n // Node.js: use in-memory storage\n const store = new Map<string, string>();\n this.storage = {\n getItem: (key: string) => store.get(key) || null,\n setItem: (key: string, value: string) => { store.set(key, value); },\n removeItem: (key: string) => { store.delete(key); }\n };\n }\n }\n\n saveSession(session: AuthSession): void {\n this.storage.setItem(TOKEN_KEY, session.accessToken);\n this.storage.setItem(USER_KEY, JSON.stringify(session.user));\n }\n\n getSession(): AuthSession | null {\n const token = this.storage.getItem(TOKEN_KEY);\n const userStr = this.storage.getItem(USER_KEY);\n\n if (!token || !userStr) {\n return null;\n }\n\n try {\n const user = JSON.parse(userStr as string);\n return { accessToken: token as string, user };\n } catch {\n this.clearSession();\n return null;\n }\n }\n\n getAccessToken(): string | null {\n const token = this.storage.getItem(TOKEN_KEY);\n return typeof token === 'string' ? token : null;\n }\n\n clearSession(): void {\n this.storage.removeItem(TOKEN_KEY);\n this.storage.removeItem(USER_KEY);\n }\n}","/**\n * Database module for InsForge SDK\n * Supabase-style query builder for PostgREST operations\n */\n\nimport { HttpClient } from '../lib/http-client';\nimport { InsForgeError } from '../types';\n\nexport interface DatabaseResponse<T> {\n data: T | null;\n error: InsForgeError | null;\n count?: number;\n}\n\n/**\n * Query builder for database operations\n * Uses method chaining like Supabase\n */\nexport class QueryBuilder<T = any> {\n private method: 'GET' | 'POST' | 'PATCH' | 'DELETE' = 'GET';\n private headers: Record<string, string> = {};\n private queryParams: Record<string, string> = {};\n private body?: any;\n\n constructor(\n private table: string,\n private http: HttpClient\n ) {}\n\n /**\n * Perform a SELECT query\n * For mutations (insert/update/delete), this enables returning data\n * @param columns - Columns to select (default: '*')\n * @example\n * .select('*')\n * .select('id, title, content')\n * .select('*, users!inner(*)') // Join with users table\n * .select('*, profile:profiles(*)') // Join with alias\n * .insert({ title: 'New' }).select() // Returns inserted data\n */\n select(columns: string = '*'): this {\n // For mutations, add return=representation header\n if (this.method !== 'GET') {\n const existingPrefer = this.headers['Prefer'] || '';\n const preferParts = existingPrefer ? [existingPrefer] : [];\n if (!preferParts.some(p => p.includes('return='))) {\n preferParts.push('return=representation');\n }\n this.headers['Prefer'] = preferParts.join(',');\n }\n \n // Always set the select parameter for GET requests\n // This enables PostgREST joins and nested queries\n if (this.method === 'GET' && columns) {\n this.queryParams.select = columns;\n } else if (columns !== '*') {\n // For mutations, only set if not default\n this.queryParams.select = columns;\n }\n return this;\n }\n\n /**\n * Perform an INSERT\n * @param values - Single object or array of objects\n * @param options - { upsert: true } for upsert behavior\n * @example\n * .insert({ title: 'Hello', content: 'World' }).select()\n * .insert([{ title: 'Post 1' }, { title: 'Post 2' }]).select()\n */\n insert(values: Partial<T> | Partial<T>[], options?: { upsert?: boolean }): this {\n this.method = 'POST';\n this.body = Array.isArray(values) ? values : [values];\n \n if (options?.upsert) {\n this.headers['Prefer'] = 'resolution=merge-duplicates';\n }\n \n return this;\n }\n\n /**\n * Perform an UPDATE\n * @param values - Object with fields to update\n * @example\n * .update({ title: 'Updated Title' }).select()\n */\n update(values: Partial<T>): this {\n this.method = 'PATCH';\n this.body = values;\n return this;\n }\n\n /**\n * Perform a DELETE\n * @example\n * .delete().select()\n */\n delete(): this {\n this.method = 'DELETE';\n return this;\n }\n\n /**\n * Perform an UPSERT\n * @param values - Single object or array of objects\n * @example\n * .upsert({ id: 1, title: 'Hello' })\n */\n upsert(values: Partial<T> | Partial<T>[]): this {\n return this.insert(values, { upsert: true });\n }\n\n // FILTERS\n\n /**\n * Filter by column equal to value\n * @example .eq('id', 123)\n */\n eq(column: string, value: any): this {\n this.queryParams[column] = `eq.${value}`;\n return this;\n }\n\n /**\n * Filter by column not equal to value\n * @example .neq('status', 'draft')\n */\n neq(column: string, value: any): this {\n this.queryParams[column] = `neq.${value}`;\n return this;\n }\n\n /**\n * Filter by column greater than value\n * @example .gt('age', 18)\n */\n gt(column: string, value: any): this {\n this.queryParams[column] = `gt.${value}`;\n return this;\n }\n\n /**\n * Filter by column greater than or equal to value\n * @example .gte('price', 100)\n */\n gte(column: string, value: any): this {\n this.queryParams[column] = `gte.${value}`;\n return this;\n }\n\n /**\n * Filter by column less than value\n * @example .lt('stock', 10)\n */\n lt(column: string, value: any): this {\n this.queryParams[column] = `lt.${value}`;\n return this;\n }\n\n /**\n * Filter by column less than or equal to value\n * @example .lte('discount', 50)\n */\n lte(column: string, value: any): this {\n this.queryParams[column] = `lte.${value}`;\n return this;\n }\n\n /**\n * Filter by pattern matching (case-sensitive)\n * @example .like('email', '%@gmail.com')\n */\n like(column: string, pattern: string): this {\n this.queryParams[column] = `like.${pattern}`;\n return this;\n }\n\n /**\n * Filter by pattern matching (case-insensitive)\n * @example .ilike('name', '%john%')\n */\n ilike(column: string, pattern: string): this {\n this.queryParams[column] = `ilike.${pattern}`;\n return this;\n }\n\n /**\n * Filter by checking if column is a value\n * @example .is('deleted_at', null)\n */\n is(column: string, value: null | boolean): this {\n if (value === null) {\n this.queryParams[column] = 'is.null';\n } else {\n this.queryParams[column] = `is.${value}`;\n }\n return this;\n }\n\n /**\n * Filter by checking if value is in array\n * @example .in('status', ['active', 'pending'])\n */\n in(column: string, values: any[]): this {\n this.queryParams[column] = `in.(${values.join(',')})`;\n return this;\n }\n\n // MODIFIERS\n\n /**\n * Order by column\n * @example \n * .order('created_at') // ascending\n * .order('created_at', { ascending: false }) // descending\n */\n order(column: string, options?: { ascending?: boolean }): this {\n const ascending = options?.ascending !== false;\n this.queryParams.order = ascending ? column : `${column}.desc`;\n return this;\n }\n\n /**\n * Limit the number of rows returned\n * @example .limit(10)\n */\n limit(count: number): this {\n this.queryParams.limit = count.toString();\n return this;\n }\n\n /**\n * Return results from an offset\n * @example .offset(20)\n */\n offset(count: number): this {\n this.queryParams.offset = count.toString();\n return this;\n }\n\n /**\n * Set a range of rows to return\n * @example .range(0, 9) // First 10 rows\n */\n range(from: number, to: number): this {\n this.headers['Range'] = `${from}-${to}`;\n return this;\n }\n\n /**\n * Return a single object instead of array\n * @example .single()\n */\n single(): this {\n this.headers['Accept'] = 'application/vnd.pgrst.object+json';\n return this;\n }\n\n /**\n * Get the total count (use with select)\n * @example .select('*', { count: 'exact' })\n */\n count(algorithm: 'exact' | 'planned' | 'estimated' = 'exact'): this {\n const prefer = this.headers['Prefer'] || '';\n this.headers['Prefer'] = prefer ? `${prefer},count=${algorithm}` : `count=${algorithm}`;\n return this;\n }\n\n /**\n * Execute the query and return results\n */\n async execute(): Promise<DatabaseResponse<T>> {\n try {\n const path = `/api/database/records/${this.table}`;\n let response: any;\n\n switch (this.method) {\n case 'GET':\n response = await this.http.get<T>(path, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n \n case 'POST':\n response = await this.http.post<T>(path, this.body, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n \n case 'PATCH':\n response = await this.http.patch<T>(path, this.body, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n \n case 'DELETE':\n response = await this.http.delete<T>(path, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n }\n\n return { data: response, error: null };\n } catch (error) {\n return {\n data: null,\n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Database operation failed',\n 500,\n 'DATABASE_ERROR'\n )\n };\n }\n }\n\n /**\n * Make QueryBuilder thenable for async/await\n */\n then<TResult1 = DatabaseResponse<T>, TResult2 = never>(\n onfulfilled?: ((value: DatabaseResponse<T>) => TResult1 | PromiseLike<TResult1>) | undefined | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null\n ): Promise<TResult1 | TResult2> {\n return this.execute().then(onfulfilled, onrejected);\n }\n}\n\n/**\n * Database client for InsForge SDK\n * Provides Supabase-style interface\n */\nexport class Database {\n constructor(private http: HttpClient) {}\n\n /**\n * Create a query builder for a table\n * @param table - The table name\n * @example\n * const { data, error } = await client.database\n * .from('posts')\n * .select('*')\n * .eq('user_id', userId)\n * .order('created_at', { ascending: false })\n * .limit(10);\n */\n from<T = any>(table: string): QueryBuilder<T> {\n return new QueryBuilder<T>(table, this.http);\n }\n}","/**\n * Auth module for InsForge SDK\n * Uses shared schemas for type safety\n */\n\nimport { HttpClient } from '../lib/http-client';\nimport { TokenManager } from '../lib/token-manager';\nimport { AuthSession, InsForgeError } from '../types';\nimport { Database } from './database';\n\nimport type {\n CreateUserRequest,\n CreateUserResponse,\n CreateSessionRequest,\n CreateSessionResponse,\n GetCurrentSessionResponse,\n GetOauthUrlResponse,\n} from '@insforge/shared-schemas';\n\nexport class Auth {\n private database: Database;\n \n constructor(\n private http: HttpClient,\n private tokenManager: TokenManager\n ) {\n this.database = new Database(http);\n \n // Auto-detect OAuth callback parameters in the URL\n this.detectOAuthCallback();\n }\n\n /**\n * Automatically detect and handle OAuth callback parameters in the URL\n * This runs on initialization to seamlessly complete the OAuth flow\n * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)\n */\n private detectOAuthCallback(): void {\n // Only run in browser environment\n if (typeof window === 'undefined') return;\n \n try {\n const params = new URLSearchParams(window.location.search);\n \n // Backend returns: access_token, user_id, email, name (optional)\n const accessToken = params.get('access_token');\n const userId = params.get('user_id');\n const email = params.get('email');\n const name = params.get('name');\n \n // Check if we have OAuth callback parameters\n if (accessToken && userId && email) {\n // Create session with the data from backend\n const session: AuthSession = {\n accessToken,\n user: {\n id: userId,\n email: email,\n name: name || '',\n // These fields are not provided by backend OAuth callback\n // They'll be populated when calling getCurrentUser()\n emailVerified: false,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n } as any,\n };\n \n // Save session and set auth token\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(accessToken);\n \n // Clean up the URL to remove sensitive parameters\n const url = new URL(window.location.href);\n url.searchParams.delete('access_token');\n url.searchParams.delete('user_id');\n url.searchParams.delete('email');\n url.searchParams.delete('name');\n \n // Also handle error case from backend (line 581)\n if (params.has('error')) {\n url.searchParams.delete('error');\n }\n \n // Replace URL without adding to browser history\n window.history.replaceState({}, document.title, url.toString());\n }\n } catch (error) {\n // Silently continue - don't break initialization\n console.debug('OAuth callback detection skipped:', error);\n }\n }\n\n /**\n * Sign up a new user\n */\n async signUp(request: CreateUserRequest): Promise<{\n data: CreateUserResponse | null;\n error: InsForgeError | null;\n }> {\n try {\n const response = await this.http.post<CreateUserResponse>('/api/auth/users', request);\n \n // Save session internally\n const session: AuthSession = {\n accessToken: response.accessToken,\n user: response.user,\n };\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(response.accessToken);\n\n return { \n data: response,\n error: null \n };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: null, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: null, \n error: new InsForgeError(\n error instanceof Error ? error.message : 'An unexpected error occurred during sign up',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Sign in with email and password\n */\n async signInWithPassword(request: CreateSessionRequest): Promise<{\n data: CreateSessionResponse | null;\n error: InsForgeError | null;\n }> {\n try {\n const response = await this.http.post<CreateSessionResponse>('/api/auth/sessions', request);\n \n // Save session internally\n const session: AuthSession = {\n accessToken: response.accessToken,\n user: response.user,\n };\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(response.accessToken);\n\n return { \n data: response,\n error: null \n };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: null, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: null, \n error: new InsForgeError(\n 'An unexpected error occurred during sign in',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Sign in with OAuth provider\n */\n async signInWithOAuth(options: {\n provider: 'google' | 'github';\n redirectTo?: string;\n skipBrowserRedirect?: boolean;\n }): Promise<{\n data: { url?: string; provider?: string };\n error: InsForgeError | null;\n }> {\n try {\n const { provider, redirectTo, skipBrowserRedirect } = options;\n \n const params = redirectTo \n ? { redirect_uri: redirectTo } \n : undefined;\n \n const endpoint = `/api/auth/oauth/${provider}`;\n const response = await this.http.get<GetOauthUrlResponse>(endpoint, { params });\n \n // Automatically redirect in browser unless told not to\n if (typeof window !== 'undefined' && !skipBrowserRedirect) {\n window.location.href = response.authUrl;\n return { data: {}, error: null };\n }\n\n return { \n data: { \n url: response.authUrl,\n provider \n }, \n error: null \n };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: {}, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: {}, \n error: new InsForgeError(\n 'An unexpected error occurred during OAuth initialization',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Sign out the current user\n */\n async signOut(): Promise<{ error: InsForgeError | null }> {\n try {\n this.tokenManager.clearSession();\n this.http.setAuthToken(null);\n return { error: null };\n } catch (error) {\n return { \n error: new InsForgeError(\n 'Failed to sign out',\n 500,\n 'SIGNOUT_ERROR'\n )\n };\n }\n }\n\n /**\n * Get the current user with full profile information\n * Returns both auth info (id, email, role) and profile data (nickname, avatar_url, bio, etc.)\n */\n async getCurrentUser(): Promise<{\n data: { user: any; profile: any } | null;\n error: InsForgeError | null;\n }> {\n try {\n // Check if we have a token\n const session = this.tokenManager.getSession();\n if (!session?.accessToken) {\n return { data: null, error: null };\n }\n\n // Call the API for auth info\n this.http.setAuthToken(session.accessToken);\n const authResponse = await this.http.get<GetCurrentSessionResponse>('/api/auth/sessions/current');\n \n // Get the user's profile using query builder\n const { data: profile, error: profileError } = await this.database\n .from('users')\n .select('*')\n .eq('id', authResponse.user.id)\n .single();\n \n if (profileError && profileError.statusCode !== 406) { // 406 = not found\n return { data: null, error: profileError };\n }\n \n return {\n data: {\n user: authResponse.user,\n profile: profile\n },\n error: null\n };\n } catch (error) {\n // If unauthorized, clear session\n if (error instanceof InsForgeError && error.statusCode === 401) {\n await this.signOut();\n return { data: null, error: null };\n }\n \n // Pass through all other errors unchanged\n if (error instanceof InsForgeError) {\n return { data: null, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: null, \n error: new InsForgeError(\n 'An unexpected error occurred while fetching user',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Get any user's profile by ID\n * Returns profile information from the users table (nickname, avatar_url, bio, etc.)\n */\n async getProfile(userId: string): Promise<{\n data: any | null;\n error: InsForgeError | null;\n }> {\n const { data, error } = await this.database\n .from('users')\n .select('*')\n .eq('id', userId)\n .single();\n \n // Handle not found as null, not error\n if (error && error.statusCode === 406) {\n return { data: null, error: null };\n }\n \n return { data, error };\n }\n\n /**\n * Get the current session (only session data, no API call)\n * Returns the stored JWT token and basic user info from local storage\n */\n async getCurrentSession(): Promise<{\n data: { session: AuthSession | null };\n error: InsForgeError | null;\n }> {\n try {\n const session = this.tokenManager.getSession();\n \n if (session?.accessToken) {\n this.http.setAuthToken(session.accessToken);\n return { data: { session }, error: null };\n }\n\n return { data: { session: null }, error: null };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: { session: null }, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: { session: null }, \n error: new InsForgeError(\n 'An unexpected error occurred while getting session',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Set/Update the current user's profile\n * Updates profile information in the users table (nickname, avatar_url, bio, etc.)\n */\n async setProfile(profile: {\n nickname?: string;\n avatar_url?: string;\n bio?: string;\n birthday?: string;\n [key: string]: any;\n }): Promise<{\n data: any | null;\n error: InsForgeError | null;\n }> {\n // Get current session to get user ID\n const session = this.tokenManager.getSession();\n if (!session?.user?.id) {\n return { \n data: null, \n error: new InsForgeError(\n 'No authenticated user found',\n 401,\n 'UNAUTHENTICATED'\n )\n };\n }\n\n // Update the profile using query builder\n return await this.database\n .from('users')\n .update(profile)\n .eq('id', session.user.id)\n .select()\n .single();\n }\n\n\n}","/**\n * Storage module for InsForge SDK\n * Handles file uploads, downloads, and bucket management\n */\n\nimport { HttpClient } from '../lib/http-client';\nimport { InsForgeError } from '../types';\nimport type { \n StorageFileSchema,\n ListObjectsResponseSchema\n} from '@insforge/shared-schemas';\n\nexport interface StorageResponse<T> {\n data: T | null;\n error: InsForgeError | null;\n}\n\n/**\n * Storage bucket operations\n */\nexport class StorageBucket {\n constructor(\n private bucketName: string,\n private http: HttpClient\n ) {}\n\n /**\n * Upload a file with a specific key\n * @param path - The object key/path\n * @param file - File or Blob to upload\n */\n async upload(\n path: string,\n file: File | Blob\n ): Promise<StorageResponse<StorageFileSchema>> {\n try {\n const formData = new FormData();\n formData.append('file', file);\n\n // Use PUT for specific path\n const response = await this.http.request<StorageFileSchema>(\n 'PUT',\n `/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`,\n {\n body: formData as any,\n headers: {\n // Don't set Content-Type, let browser set multipart boundary\n }\n }\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Upload failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Upload a file with auto-generated key\n * @param file - File or Blob to upload\n */\n async uploadAuto(\n file: File | Blob\n ): Promise<StorageResponse<StorageFileSchema>> {\n try {\n const formData = new FormData();\n formData.append('file', file);\n\n // Use POST for auto-generated key\n const response = await this.http.request<StorageFileSchema>(\n 'POST',\n `/api/storage/buckets/${this.bucketName}/objects`,\n {\n body: formData as any,\n headers: {\n // Don't set Content-Type, let browser set multipart boundary\n }\n }\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Upload failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Download a file\n * @param path - The object key/path\n * Returns the file as a Blob\n */\n async download(path: string): Promise<{ data: Blob | null; error: InsForgeError | null }> {\n try {\n // For binary data, we need to use fetch directly with proper response handling\n // The http.request method expects JSON responses, so we can't use it for blobs\n const url = `${this.http.baseUrl}/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`;\n \n const response = await this.http.fetch(url, {\n method: 'GET',\n headers: this.http.getHeaders()\n });\n\n if (!response.ok) {\n try {\n const error = await response.json();\n throw InsForgeError.fromApiError(error);\n } catch {\n throw new InsForgeError(\n `Download failed: ${response.statusText}`,\n response.status,\n 'STORAGE_ERROR'\n );\n }\n }\n\n const blob = await response.blob();\n return { data: blob, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Download failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Get public URL for a file\n * @param path - The object key/path\n */\n getPublicUrl(path: string): string {\n return `${this.http.baseUrl}/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`;\n }\n\n /**\n * List objects in the bucket\n * @param prefix - Filter by key prefix\n * @param search - Search in file names\n * @param limit - Maximum number of results (default: 100, max: 1000)\n * @param offset - Number of results to skip\n */\n async list(options?: {\n prefix?: string;\n search?: string;\n limit?: number;\n offset?: number;\n }): Promise<StorageResponse<ListObjectsResponseSchema>> {\n try {\n const params: Record<string, string> = {};\n \n if (options?.prefix) params.prefix = options.prefix;\n if (options?.search) params.search = options.search;\n if (options?.limit) params.limit = options.limit.toString();\n if (options?.offset) params.offset = options.offset.toString();\n\n const response = await this.http.get<ListObjectsResponseSchema>(\n `/api/storage/buckets/${this.bucketName}/objects`,\n { params }\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'List failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Delete a file\n * @param path - The object key/path\n */\n async remove(path: string): Promise<StorageResponse<{ message: string }>> {\n try {\n const response = await this.http.delete<{ message: string }>(\n `/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Delete failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n}\n\n/**\n * Storage module for file operations\n */\nexport class Storage {\n constructor(private http: HttpClient) {}\n\n /**\n * Get a bucket instance for operations\n * @param bucketName - Name of the bucket\n */\n from(bucketName: string): StorageBucket {\n return new StorageBucket(bucketName, this.http);\n }\n}","/**\n * AI Module for Insforge SDK\n * Wrapper for AI endpoints that follows OpenAI-like patterns\n * \n * The backend handles all the complexity of different AI providers\n * and returns a unified format. This SDK just calls the endpoints.\n */\n\nimport { HttpClient } from '../lib/http-client';\n\nexport class AI {\n public readonly chat: Chat;\n public readonly images: Images;\n\n constructor(private http: HttpClient) {\n this.chat = new Chat(http);\n this.images = new Images(http);\n }\n}\n\nclass Chat {\n public readonly completions: ChatCompletions;\n\n constructor(http: HttpClient) {\n this.completions = new ChatCompletions(http);\n }\n}\n\nclass ChatCompletions {\n constructor(private http: HttpClient) {}\n\n /**\n * Create a chat completion\n * \n * @example\n * ```typescript\n * // Non-streaming\n * const response = await client.ai.chat.completions.create({\n * model: 'gpt-4',\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n * console.log(response.response);\n * \n * // Streaming - returns async iterable\n * const stream = await client.ai.chat.completions.create({\n * model: 'gpt-4',\n * messages: [{ role: 'user', content: 'Tell me a story' }],\n * stream: true\n * });\n * \n * for await (const event of stream) {\n * if (event.chunk) {\n * process.stdout.write(event.chunk);\n * }\n * if (event.done) {\n * console.log('Stream complete!');\n * }\n * }\n * ```\n */\n async create(params: {\n model: string;\n messages?: Array<{ role: 'user' | 'assistant' | 'system'; content: string }>;\n message?: string;\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n systemPrompt?: string;\n stream?: boolean;\n }): Promise<any> {\n // For streaming, return an async iterable that yields parsed SSE events\n if (params.stream) {\n const headers = this.http.getHeaders();\n headers['Content-Type'] = 'application/json';\n \n const response = await this.http.fetch(\n `${this.http.baseUrl}/api/ai/chat`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(params)\n }\n );\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.error || 'Stream request failed');\n }\n\n // Return async iterable that parses SSE for the user\n return this.parseSSEStream(response);\n }\n\n // Non-streaming: use regular post method\n return this.http.post('/api/ai/chat', params);\n }\n\n /**\n * Parse SSE stream into async iterable of parsed events\n * Users don't need to handle SSE parsing themselves\n */\n private async *parseSSEStream(response: Response): AsyncIterableIterator<any> {\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const dataStr = line.slice(6).trim();\n if (dataStr) {\n try {\n const data = JSON.parse(dataStr);\n yield data;\n \n // If we received the done signal, we can stop\n if (data.done) {\n reader.releaseLock();\n return;\n }\n } catch (e) {\n // Skip invalid JSON\n console.warn('Failed to parse SSE data:', dataStr);\n }\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n\nclass Images {\n constructor(private http: HttpClient) {}\n\n /**\n * Generate images\n * \n * @example\n * ```typescript\n * const response = await client.ai.images.generate({\n * model: 'dall-e-3',\n * prompt: 'A sunset over mountains',\n * numImages: 1,\n * size: '1024x1024'\n * });\n * console.log(response.images[0].url);\n * ```\n */\n async generate(params: {\n model: string;\n prompt: string;\n negativePrompt?: string;\n width?: number;\n height?: number;\n numImages?: number;\n quality?: 'standard' | 'hd';\n style?: 'vivid' | 'natural';\n responseFormat?: 'url' | 'b64_json';\n size?: string;\n }) {\n // Backend expects these exact field names\n return this.http.post('/api/ai/image/generation', params);\n }\n}","import { InsForgeConfig } from './types';\nimport { HttpClient } from './lib/http-client';\nimport { TokenManager } from './lib/token-manager';\nimport { Auth } from './modules/auth';\nimport { Database } from './modules/database';\nimport { Storage } from './modules/storage';\nimport { AI } from './modules/ai';\n\n/**\n * Main InsForge SDK Client\n * \n * @example\n * ```typescript\n * import { InsForgeClient } from '@insforge/sdk';\n * \n * const client = new InsForgeClient({\n * baseUrl: 'http://localhost:7130'\n * });\n * \n * // Authentication\n * const session = await client.auth.register({\n * email: 'user@example.com',\n * password: 'password123',\n * name: 'John Doe'\n * });\n * \n * // Database operations\n * const { data, error } = await client.database\n * .from('posts')\n * .select('*')\n * .eq('user_id', session.user.id)\n * .order('created_at', { ascending: false })\n * .limit(10);\n * \n * // Insert data\n * const { data: newPost } = await client.database\n * .from('posts')\n * .insert({ title: 'Hello', content: 'World' })\n * .single();\n * ```\n */\nexport class InsForgeClient {\n private http: HttpClient;\n private tokenManager: TokenManager;\n \n public readonly auth: Auth;\n public readonly database: Database;\n public readonly storage: Storage;\n public readonly ai: AI;\n\n constructor(config: InsForgeConfig = {}) {\n this.http = new HttpClient(config);\n this.tokenManager = new TokenManager(config.storage);\n \n this.auth = new Auth(\n this.http,\n this.tokenManager\n );\n \n this.database = new Database(this.http);\n this.storage = new Storage(this.http);\n this.ai = new AI(this.http);\n }\n\n\n /**\n * Set a custom API key for authentication\n * This is useful for server-to-server communication\n * \n * @param apiKey - The API key (should start with 'ik_')\n * \n * @example\n * ```typescript\n * client.setApiKey('ik_your_api_key_here');\n * ```\n */\n setApiKey(apiKey: string): void {\n // API keys can be used as Bearer tokens\n this.http.setAuthToken(apiKey);\n }\n\n /**\n * Get the underlying HTTP client for custom requests\n * \n * @example\n * ```typescript\n * const httpClient = client.getHttpClient();\n * const customData = await httpClient.get('/api/custom-endpoint');\n * ```\n */\n getHttpClient(): HttpClient {\n return this.http;\n }\n\n /**\n * Future modules will be added here:\n * - database: Database operations\n * - storage: File storage operations\n * - functions: Serverless functions\n * - tables: Table management\n * - metadata: Backend metadata\n */\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACmEO,IAAM,gBAAN,MAAM,uBAAsB,MAAM;AAAA,EAKvC,YAAY,SAAiB,YAAoB,OAAe,aAAsB;AACpF,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,QAAQ;AACb,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,OAAO,aAAa,UAAmC;AACrD,WAAO,IAAI;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,EACF;AACF;;;AClFO,IAAM,aAAN,MAAiB;AAAA,EAKtB,YAAY,QAAwB;AAClC,SAAK,UAAU,OAAO,WAAW;AAEjC,SAAK,QAAQ,OAAO,UAAU,WAAW,QAAQ,WAAW,MAAM,KAAK,UAAU,IAAI;AACrF,SAAK,iBAAiB;AAAA,MACpB,GAAG,OAAO;AAAA,IACZ;AAGA,QAAI,OAAO,QAAQ;AACjB,WAAK,eAAe,eAAe,IAAI,UAAU,OAAO,MAAM;AAAA,IAChE;AAEA,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,SAAS,MAAc,QAAyC;AACtE,UAAM,MAAM,IAAI,IAAI,MAAM,KAAK,OAAO;AACtC,QAAI,QAAQ;AACV,aAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAG/C,YAAI,QAAQ,UAAU;AAEpB,gBAAM,kBAAkB,MAAM,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACxD,cAAI,aAAa,OAAO,KAAK,eAAe;AAAA,QAC9C,OAAO;AACL,cAAI,aAAa,OAAO,KAAK,KAAK;AAAA,QACpC;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA,EAEA,MAAM,QACJ,QACA,MACA,UAA0B,CAAC,GACf;AACZ,UAAM,EAAE,QAAQ,UAAU,CAAC,GAAG,MAAM,GAAG,aAAa,IAAI;AAExD,UAAM,MAAM,KAAK,SAAS,MAAM,MAAM;AAEtC,UAAM,iBAAyC;AAAA,MAC7C,GAAG,KAAK;AAAA,IACV;AAGA,QAAI;AACJ,QAAI,SAAS,QAAW;AAEtB,UAAI,OAAO,aAAa,eAAe,gBAAgB,UAAU;AAE/D,wBAAgB;AAAA,MAClB,OAAO;AAEL,YAAI,WAAW,OAAO;AACpB,yBAAe,cAAc,IAAI;AAAA,QACnC;AACA,wBAAgB,KAAK,UAAU,IAAI;AAAA,MACrC;AAAA,IACF;AAEA,WAAO,OAAO,gBAAgB,OAAO;AAErC,UAAM,WAAW,MAAM,KAAK,MAAM,KAAK;AAAA,MACrC;AAAA,MACA,SAAS;AAAA,MACT,MAAM;AAAA,MACN,GAAG;AAAA,IACL,CAAC;AAGD,QAAI,SAAS,WAAW,KAAK;AAC3B,aAAO;AAAA,IACT;AAGA,QAAI;AACJ,UAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;AAEvD,QAAI,aAAa,SAAS,MAAM,GAAG;AACjC,aAAO,MAAM,SAAS,KAAK;AAAA,IAC7B,OAAO;AAEL,aAAO,MAAM,SAAS,KAAK;AAAA,IAC7B;AAGA,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI,QAAQ,OAAO,SAAS,YAAY,WAAW,MAAM;AACvD,cAAM,cAAc,aAAa,IAAgB;AAAA,MACnD;AACA,YAAM,IAAI;AAAA,QACR,mBAAmB,SAAS,UAAU;AAAA,QACtC,SAAS;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,IAAO,MAAc,SAAsC;AACzD,WAAO,KAAK,QAAW,OAAO,MAAM,OAAO;AAAA,EAC7C;AAAA,EAEA,KAAQ,MAAc,MAAY,SAAsC;AACtE,WAAO,KAAK,QAAW,QAAQ,MAAM,EAAE,GAAG,SAAS,KAAK,CAAC;AAAA,EAC3D;AAAA,EAEA,IAAO,MAAc,MAAY,SAAsC;AACrE,WAAO,KAAK,QAAW,OAAO,MAAM,EAAE,GAAG,SAAS,KAAK,CAAC;AAAA,EAC1D;AAAA,EAEA,MAAS,MAAc,MAAY,SAAsC;AACvE,WAAO,KAAK,QAAW,SAAS,MAAM,EAAE,GAAG,SAAS,KAAK,CAAC;AAAA,EAC5D;AAAA,EAEA,OAAU,MAAc,SAAsC;AAC5D,WAAO,KAAK,QAAW,UAAU,MAAM,OAAO;AAAA,EAChD;AAAA,EAEA,aAAa,OAAsB;AACjC,QAAI,OAAO;AACT,WAAK,eAAe,eAAe,IAAI,UAAU,KAAK;AAAA,IACxD,OAAO;AACL,aAAO,KAAK,eAAe,eAAe;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,aAAqC;AACnC,WAAO,EAAE,GAAG,KAAK,eAAe;AAAA,EAClC;AACF;;;ACnJA,IAAM,YAAY;AAClB,IAAM,WAAW;AAEV,IAAM,eAAN,MAAmB;AAAA,EAGxB,YAAY,SAAwB;AAClC,QAAI,SAAS;AAEX,WAAK,UAAU;AAAA,IACjB,WAAW,OAAO,WAAW,eAAe,OAAO,cAAc;AAE/D,WAAK,UAAU,OAAO;AAAA,IACxB,OAAO;AAEL,YAAM,QAAQ,oBAAI,IAAoB;AACtC,WAAK,UAAU;AAAA,QACb,SAAS,CAAC,QAAgB,MAAM,IAAI,GAAG,KAAK;AAAA,QAC5C,SAAS,CAAC,KAAa,UAAkB;AAAE,gBAAM,IAAI,KAAK,KAAK;AAAA,QAAG;AAAA,QAClE,YAAY,CAAC,QAAgB;AAAE,gBAAM,OAAO,GAAG;AAAA,QAAG;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY,SAA4B;AACtC,SAAK,QAAQ,QAAQ,WAAW,QAAQ,WAAW;AACnD,SAAK,QAAQ,QAAQ,UAAU,KAAK,UAAU,QAAQ,IAAI,CAAC;AAAA,EAC7D;AAAA,EAEA,aAAiC;AAC/B,UAAM,QAAQ,KAAK,QAAQ,QAAQ,SAAS;AAC5C,UAAM,UAAU,KAAK,QAAQ,QAAQ,QAAQ;AAE7C,QAAI,CAAC,SAAS,CAAC,SAAS;AACtB,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,OAAO,KAAK,MAAM,OAAiB;AACzC,aAAO,EAAE,aAAa,OAAiB,KAAK;AAAA,IAC9C,QAAQ;AACN,WAAK,aAAa;AAClB,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,iBAAgC;AAC9B,UAAM,QAAQ,KAAK,QAAQ,QAAQ,SAAS;AAC5C,WAAO,OAAO,UAAU,WAAW,QAAQ;AAAA,EAC7C;AAAA,EAEA,eAAqB;AACnB,SAAK,QAAQ,WAAW,SAAS;AACjC,SAAK,QAAQ,WAAW,QAAQ;AAAA,EAClC;AACF;;;ACvCO,IAAM,eAAN,MAA4B;AAAA,EAMjC,YACU,OACA,MACR;AAFQ;AACA;AAPV,SAAQ,SAA8C;AACtD,SAAQ,UAAkC,CAAC;AAC3C,SAAQ,cAAsC,CAAC;AAAA,EAM5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaH,OAAO,UAAkB,KAAW;AAElC,QAAI,KAAK,WAAW,OAAO;AACzB,YAAM,iBAAiB,KAAK,QAAQ,QAAQ,KAAK;AACjD,YAAM,cAAc,iBAAiB,CAAC,cAAc,IAAI,CAAC;AACzD,UAAI,CAAC,YAAY,KAAK,OAAK,EAAE,SAAS,SAAS,CAAC,GAAG;AACjD,oBAAY,KAAK,uBAAuB;AAAA,MAC1C;AACA,WAAK,QAAQ,QAAQ,IAAI,YAAY,KAAK,GAAG;AAAA,IAC/C;AAIA,QAAI,KAAK,WAAW,SAAS,SAAS;AACpC,WAAK,YAAY,SAAS;AAAA,IAC5B,WAAW,YAAY,KAAK;AAE1B,WAAK,YAAY,SAAS;AAAA,IAC5B;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAO,QAAmC,SAAsC;AAC9E,SAAK,SAAS;AACd,SAAK,OAAO,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AAEpD,QAAI,SAAS,QAAQ;AACnB,WAAK,QAAQ,QAAQ,IAAI;AAAA,IAC3B;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,QAA0B;AAC/B,SAAK,SAAS;AACd,SAAK,OAAO;AACZ,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAe;AACb,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,QAAyC;AAC9C,WAAO,KAAK,OAAO,QAAQ,EAAE,QAAQ,KAAK,CAAC;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,GAAG,QAAgB,OAAkB;AACnC,SAAK,YAAY,MAAM,IAAI,MAAM,KAAK;AACtC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,QAAgB,OAAkB;AACpC,SAAK,YAAY,MAAM,IAAI,OAAO,KAAK;AACvC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,GAAG,QAAgB,OAAkB;AACnC,SAAK,YAAY,MAAM,IAAI,MAAM,KAAK;AACtC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,QAAgB,OAAkB;AACpC,SAAK,YAAY,MAAM,IAAI,OAAO,KAAK;AACvC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,GAAG,QAAgB,OAAkB;AACnC,SAAK,YAAY,MAAM,IAAI,MAAM,KAAK;AACtC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,QAAgB,OAAkB;AACpC,SAAK,YAAY,MAAM,IAAI,OAAO,KAAK;AACvC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,QAAgB,SAAuB;AAC1C,SAAK,YAAY,MAAM,IAAI,QAAQ,OAAO;AAC1C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAgB,SAAuB;AAC3C,SAAK,YAAY,MAAM,IAAI,SAAS,OAAO;AAC3C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,GAAG,QAAgB,OAA6B;AAC9C,QAAI,UAAU,MAAM;AAClB,WAAK,YAAY,MAAM,IAAI;AAAA,IAC7B,OAAO;AACL,WAAK,YAAY,MAAM,IAAI,MAAM,KAAK;AAAA,IACxC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,GAAG,QAAgB,QAAqB;AACtC,SAAK,YAAY,MAAM,IAAI,OAAO,OAAO,KAAK,GAAG,CAAC;AAClD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QAAgB,SAAyC;AAC7D,UAAM,YAAY,SAAS,cAAc;AACzC,SAAK,YAAY,QAAQ,YAAY,SAAS,GAAG,MAAM;AACvD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAqB;AACzB,SAAK,YAAY,QAAQ,MAAM,SAAS;AACxC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,OAAqB;AAC1B,SAAK,YAAY,SAAS,MAAM,SAAS;AACzC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAc,IAAkB;AACpC,SAAK,QAAQ,OAAO,IAAI,GAAG,IAAI,IAAI,EAAE;AACrC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAe;AACb,SAAK,QAAQ,QAAQ,IAAI;AACzB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAA+C,SAAe;AAClE,UAAM,SAAS,KAAK,QAAQ,QAAQ,KAAK;AACzC,SAAK,QAAQ,QAAQ,IAAI,SAAS,GAAG,MAAM,UAAU,SAAS,KAAK,SAAS,SAAS;AACrF,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAwC;AAC5C,QAAI;AACF,YAAM,OAAO,yBAAyB,KAAK,KAAK;AAChD,UAAI;AAEJ,cAAQ,KAAK,QAAQ;AAAA,QACnB,KAAK;AACH,qBAAW,MAAM,KAAK,KAAK,IAAO,MAAM;AAAA,YACtC,QAAQ,KAAK;AAAA,YACb,SAAS,KAAK;AAAA,UAChB,CAAC;AACD;AAAA,QAEF,KAAK;AACH,qBAAW,MAAM,KAAK,KAAK,KAAQ,MAAM,KAAK,MAAM;AAAA,YAClD,QAAQ,KAAK;AAAA,YACb,SAAS,KAAK;AAAA,UAChB,CAAC;AACD;AAAA,QAEF,KAAK;AACH,qBAAW,MAAM,KAAK,KAAK,MAAS,MAAM,KAAK,MAAM;AAAA,YACnD,QAAQ,KAAK;AAAA,YACb,SAAS,KAAK;AAAA,UAChB,CAAC;AACD;AAAA,QAEF,KAAK;AACH,qBAAW,MAAM,KAAK,KAAK,OAAU,MAAM;AAAA,YACzC,QAAQ,KAAK;AAAA,YACb,SAAS,KAAK;AAAA,UAChB,CAAC;AACD;AAAA,MACJ;AAEA,aAAO,EAAE,MAAM,UAAU,OAAO,KAAK;AAAA,IACvC,SAAS,OAAO;AACd,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,iBAAiB,gBAAgB,QAAQ,IAAI;AAAA,UAClD;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,KACE,aACA,YAC8B;AAC9B,WAAO,KAAK,QAAQ,EAAE,KAAK,aAAa,UAAU;AAAA,EACpD;AACF;AAMO,IAAM,WAAN,MAAe;AAAA,EACpB,YAAoB,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAavC,KAAc,OAAgC;AAC5C,WAAO,IAAI,aAAgB,OAAO,KAAK,IAAI;AAAA,EAC7C;AACF;;;AC7UO,IAAM,OAAN,MAAW;AAAA,EAGhB,YACU,MACA,cACR;AAFQ;AACA;AAER,SAAK,WAAW,IAAI,SAAS,IAAI;AAGjC,SAAK,oBAAoB;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,sBAA4B;AAElC,QAAI,OAAO,WAAW,YAAa;AAEnC,QAAI;AACF,YAAM,SAAS,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAGzD,YAAM,cAAc,OAAO,IAAI,cAAc;AAC7C,YAAM,SAAS,OAAO,IAAI,SAAS;AACnC,YAAM,QAAQ,OAAO,IAAI,OAAO;AAChC,YAAM,OAAO,OAAO,IAAI,MAAM;AAG9B,UAAI,eAAe,UAAU,OAAO;AAElC,cAAM,UAAuB;AAAA,UAC3B;AAAA,UACA,MAAM;AAAA,YACJ,IAAI;AAAA,YACJ;AAAA,YACA,MAAM,QAAQ;AAAA;AAAA;AAAA,YAGd,eAAe;AAAA,YACf,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,YAClC,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UACpC;AAAA,QACF;AAGA,aAAK,aAAa,YAAY,OAAO;AACrC,aAAK,KAAK,aAAa,WAAW;AAGlC,cAAM,MAAM,IAAI,IAAI,OAAO,SAAS,IAAI;AACxC,YAAI,aAAa,OAAO,cAAc;AACtC,YAAI,aAAa,OAAO,SAAS;AACjC,YAAI,aAAa,OAAO,OAAO;AAC/B,YAAI,aAAa,OAAO,MAAM;AAG9B,YAAI,OAAO,IAAI,OAAO,GAAG;AACvB,cAAI,aAAa,OAAO,OAAO;AAAA,QACjC;AAGA,eAAO,QAAQ,aAAa,CAAC,GAAG,SAAS,OAAO,IAAI,SAAS,CAAC;AAAA,MAChE;AAAA,IACF,SAAS,OAAO;AAEd,cAAQ,MAAM,qCAAqC,KAAK;AAAA,IAC1D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,SAGV;AACD,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,KAAK,KAAyB,mBAAmB,OAAO;AAGpF,YAAM,UAAuB;AAAA,QAC3B,aAAa,SAAS;AAAA,QACtB,MAAM,SAAS;AAAA,MACjB;AACA,WAAK,aAAa,YAAY,OAAO;AACrC,WAAK,KAAK,aAAa,SAAS,WAAW;AAE3C,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,SAAS,OAAO;AAEd,UAAI,iBAAiB,eAAe;AAClC,eAAO,EAAE,MAAM,MAAM,MAAM;AAAA,MAC7B;AAGA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,IAAI;AAAA,UACT,iBAAiB,QAAQ,MAAM,UAAU;AAAA,UACzC;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAmB,SAGtB;AACD,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,KAAK,KAA4B,sBAAsB,OAAO;AAG1F,YAAM,UAAuB;AAAA,QAC3B,aAAa,SAAS;AAAA,QACtB,MAAM,SAAS;AAAA,MACjB;AACA,WAAK,aAAa,YAAY,OAAO;AACrC,WAAK,KAAK,aAAa,SAAS,WAAW;AAE3C,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,SAAS,OAAO;AAEd,UAAI,iBAAiB,eAAe;AAClC,eAAO,EAAE,MAAM,MAAM,MAAM;AAAA,MAC7B;AAGA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,IAAI;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,SAOnB;AACD,QAAI;AACF,YAAM,EAAE,UAAU,YAAY,oBAAoB,IAAI;AAEtD,YAAM,SAAS,aACX,EAAE,cAAc,WAAW,IAC3B;AAEJ,YAAM,WAAW,mBAAmB,QAAQ;AAC5C,YAAM,WAAW,MAAM,KAAK,KAAK,IAAyB,UAAU,EAAE,OAAO,CAAC;AAG9E,UAAI,OAAO,WAAW,eAAe,CAAC,qBAAqB;AACzD,eAAO,SAAS,OAAO,SAAS;AAChC,eAAO,EAAE,MAAM,CAAC,GAAG,OAAO,KAAK;AAAA,MACjC;AAEA,aAAO;AAAA,QACL,MAAM;AAAA,UACJ,KAAK,SAAS;AAAA,UACd;AAAA,QACF;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF,SAAS,OAAO;AAEd,UAAI,iBAAiB,eAAe;AAClC,eAAO,EAAE,MAAM,CAAC,GAAG,MAAM;AAAA,MAC3B;AAGA,aAAO;AAAA,QACL,MAAM,CAAC;AAAA,QACP,OAAO,IAAI;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAoD;AACxD,QAAI;AACF,WAAK,aAAa,aAAa;AAC/B,WAAK,KAAK,aAAa,IAAI;AAC3B,aAAO,EAAE,OAAO,KAAK;AAAA,IACvB,SAAS,OAAO;AACd,aAAO;AAAA,QACL,OAAO,IAAI;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,iBAGH;AACD,QAAI;AAEF,YAAM,UAAU,KAAK,aAAa,WAAW;AAC7C,UAAI,CAAC,SAAS,aAAa;AACzB,eAAO,EAAE,MAAM,MAAM,OAAO,KAAK;AAAA,MACnC;AAGA,WAAK,KAAK,aAAa,QAAQ,WAAW;AAC1C,YAAM,eAAe,MAAM,KAAK,KAAK,IAA+B,4BAA4B;AAGhG,YAAM,EAAE,MAAM,SAAS,OAAO,aAAa,IAAI,MAAM,KAAK,SACvD,KAAK,OAAO,EACZ,OAAO,GAAG,EACV,GAAG,MAAM,aAAa,KAAK,EAAE,EAC7B,OAAO;AAEV,UAAI,gBAAgB,aAAa,eAAe,KAAK;AACnD,eAAO,EAAE,MAAM,MAAM,OAAO,aAAa;AAAA,MAC3C;AAEA,aAAO;AAAA,QACL,MAAM;AAAA,UACJ,MAAM,aAAa;AAAA,UACnB;AAAA,QACF;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF,SAAS,OAAO;AAEd,UAAI,iBAAiB,iBAAiB,MAAM,eAAe,KAAK;AAC9D,cAAM,KAAK,QAAQ;AACnB,eAAO,EAAE,MAAM,MAAM,OAAO,KAAK;AAAA,MACnC;AAGA,UAAI,iBAAiB,eAAe;AAClC,eAAO,EAAE,MAAM,MAAM,MAAM;AAAA,MAC7B;AAGA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,IAAI;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAW,QAGd;AACD,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,KAAK,SAChC,KAAK,OAAO,EACZ,OAAO,GAAG,EACV,GAAG,MAAM,MAAM,EACf,OAAO;AAGV,QAAI,SAAS,MAAM,eAAe,KAAK;AACrC,aAAO,EAAE,MAAM,MAAM,OAAO,KAAK;AAAA,IACnC;AAEA,WAAO,EAAE,MAAM,MAAM;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,oBAGH;AACD,QAAI;AACF,YAAM,UAAU,KAAK,aAAa,WAAW;AAE7C,UAAI,SAAS,aAAa;AACxB,aAAK,KAAK,aAAa,QAAQ,WAAW;AAC1C,eAAO,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,KAAK;AAAA,MAC1C;AAEA,aAAO,EAAE,MAAM,EAAE,SAAS,KAAK,GAAG,OAAO,KAAK;AAAA,IAChD,SAAS,OAAO;AAEd,UAAI,iBAAiB,eAAe;AAClC,eAAO,EAAE,MAAM,EAAE,SAAS,KAAK,GAAG,MAAM;AAAA,MAC1C;AAGA,aAAO;AAAA,QACL,MAAM,EAAE,SAAS,KAAK;AAAA,QACtB,OAAO,IAAI;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAW,SASd;AAED,UAAM,UAAU,KAAK,aAAa,WAAW;AAC7C,QAAI,CAAC,SAAS,MAAM,IAAI;AACtB,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,IAAI;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,WAAO,MAAM,KAAK,SACf,KAAK,OAAO,EACZ,OAAO,OAAO,EACd,GAAG,MAAM,QAAQ,KAAK,EAAE,EACxB,OAAO,EACP,OAAO;AAAA,EACZ;AAGF;;;AC1XO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YACU,YACA,MACR;AAFQ;AACA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOH,MAAM,OACJ,MACA,MAC6C;AAC7C,QAAI;AACF,YAAM,WAAW,IAAI,SAAS;AAC9B,eAAS,OAAO,QAAQ,IAAI;AAG5B,YAAM,WAAW,MAAM,KAAK,KAAK;AAAA,QAC/B;AAAA,QACA,wBAAwB,KAAK,UAAU,YAAY,mBAAmB,IAAI,CAAC;AAAA,QAC3E;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA;AAAA,UAET;AAAA,QACF;AAAA,MACF;AAEA,aAAO,EAAE,MAAM,UAAU,OAAO,KAAK;AAAA,IACvC,SAAS,OAAO;AACd,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,iBAAiB,gBAAgB,QAAQ,IAAI;AAAA,UAClD;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WACJ,MAC6C;AAC7C,QAAI;AACF,YAAM,WAAW,IAAI,SAAS;AAC9B,eAAS,OAAO,QAAQ,IAAI;AAG5B,YAAM,WAAW,MAAM,KAAK,KAAK;AAAA,QAC/B;AAAA,QACA,wBAAwB,KAAK,UAAU;AAAA,QACvC;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA;AAAA,UAET;AAAA,QACF;AAAA,MACF;AAEA,aAAO,EAAE,MAAM,UAAU,OAAO,KAAK;AAAA,IACvC,SAAS,OAAO;AACd,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,iBAAiB,gBAAgB,QAAQ,IAAI;AAAA,UAClD;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAAS,MAA2E;AACxF,QAAI;AAGF,YAAM,MAAM,GAAG,KAAK,KAAK,OAAO,wBAAwB,KAAK,UAAU,YAAY,mBAAmB,IAAI,CAAC;AAE3G,YAAM,WAAW,MAAM,KAAK,KAAK,MAAM,KAAK;AAAA,QAC1C,QAAQ;AAAA,QACR,SAAS,KAAK,KAAK,WAAW;AAAA,MAChC,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,YAAI;AACF,gBAAM,QAAQ,MAAM,SAAS,KAAK;AAClC,gBAAM,cAAc,aAAa,KAAK;AAAA,QACxC,QAAQ;AACN,gBAAM,IAAI;AAAA,YACR,oBAAoB,SAAS,UAAU;AAAA,YACvC,SAAS;AAAA,YACT;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,aAAO,EAAE,MAAM,MAAM,OAAO,KAAK;AAAA,IACnC,SAAS,OAAO;AACd,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,iBAAiB,gBAAgB,QAAQ,IAAI;AAAA,UAClD;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,MAAsB;AACjC,WAAO,GAAG,KAAK,KAAK,OAAO,wBAAwB,KAAK,UAAU,YAAY,mBAAmB,IAAI,CAAC;AAAA,EACxG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,KAAK,SAK6C;AACtD,QAAI;AACF,YAAM,SAAiC,CAAC;AAExC,UAAI,SAAS,OAAQ,QAAO,SAAS,QAAQ;AAC7C,UAAI,SAAS,OAAQ,QAAO,SAAS,QAAQ;AAC7C,UAAI,SAAS,MAAO,QAAO,QAAQ,QAAQ,MAAM,SAAS;AAC1D,UAAI,SAAS,OAAQ,QAAO,SAAS,QAAQ,OAAO,SAAS;AAE7D,YAAM,WAAW,MAAM,KAAK,KAAK;AAAA,QAC/B,wBAAwB,KAAK,UAAU;AAAA,QACvC,EAAE,OAAO;AAAA,MACX;AAEA,aAAO,EAAE,MAAM,UAAU,OAAO,KAAK;AAAA,IACvC,SAAS,OAAO;AACd,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,iBAAiB,gBAAgB,QAAQ,IAAI;AAAA,UAClD;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,MAA6D;AACxE,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,KAAK;AAAA,QAC/B,wBAAwB,KAAK,UAAU,YAAY,mBAAmB,IAAI,CAAC;AAAA,MAC7E;AAEA,aAAO,EAAE,MAAM,UAAU,OAAO,KAAK;AAAA,IACvC,SAAS,OAAO;AACd,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,iBAAiB,gBAAgB,QAAQ,IAAI;AAAA,UAClD;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAKO,IAAM,UAAN,MAAc;AAAA,EACnB,YAAoB,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvC,KAAK,YAAmC;AACtC,WAAO,IAAI,cAAc,YAAY,KAAK,IAAI;AAAA,EAChD;AACF;;;ACzNO,IAAM,KAAN,MAAS;AAAA,EAId,YAAoB,MAAkB;AAAlB;AAClB,SAAK,OAAO,IAAI,KAAK,IAAI;AACzB,SAAK,SAAS,IAAI,OAAO,IAAI;AAAA,EAC/B;AACF;AAEA,IAAM,OAAN,MAAW;AAAA,EAGT,YAAY,MAAkB;AAC5B,SAAK,cAAc,IAAI,gBAAgB,IAAI;AAAA,EAC7C;AACF;AAEA,IAAM,kBAAN,MAAsB;AAAA,EACpB,YAAoB,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA+BvC,MAAM,OAAO,QASI;AAEf,QAAI,OAAO,QAAQ;AACjB,YAAM,UAAU,KAAK,KAAK,WAAW;AACrC,cAAQ,cAAc,IAAI;AAE1B,YAAM,WAAW,MAAM,KAAK,KAAK;AAAA,QAC/B,GAAG,KAAK,KAAK,OAAO;AAAA,QACpB;AAAA,UACE,QAAQ;AAAA,UACR;AAAA,UACA,MAAM,KAAK,UAAU,MAAM;AAAA,QAC7B;AAAA,MACF;AAEA,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,QAAQ,MAAM,SAAS,KAAK;AAClC,cAAM,IAAI,MAAM,MAAM,SAAS,uBAAuB;AAAA,MACxD;AAGA,aAAO,KAAK,eAAe,QAAQ;AAAA,IACrC;AAGA,WAAO,KAAK,KAAK,KAAK,gBAAgB,MAAM;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAe,eAAe,UAAgD;AAC5E,UAAM,SAAS,SAAS,KAAM,UAAU;AACxC,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,SAAS;AAEb,QAAI;AACF,aAAO,MAAM;AACX,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,YAAI,KAAM;AAEV,kBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,cAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,iBAAS,MAAM,IAAI,KAAK;AAExB,mBAAW,QAAQ,OAAO;AACxB,cAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,kBAAM,UAAU,KAAK,MAAM,CAAC,EAAE,KAAK;AACnC,gBAAI,SAAS;AACX,kBAAI;AACF,sBAAM,OAAO,KAAK,MAAM,OAAO;AAC/B,sBAAM;AAGN,oBAAI,KAAK,MAAM;AACb,yBAAO,YAAY;AACnB;AAAA,gBACF;AAAA,cACF,SAAS,GAAG;AAEV,wBAAQ,KAAK,6BAA6B,OAAO;AAAA,cACnD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,UAAE;AACA,aAAO,YAAY;AAAA,IACrB;AAAA,EACF;AACF;AAEA,IAAM,SAAN,MAAa;AAAA,EACX,YAAoB,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBvC,MAAM,SAAS,QAWZ;AAED,WAAO,KAAK,KAAK,KAAK,4BAA4B,MAAM;AAAA,EAC1D;AACF;;;ACrIO,IAAM,iBAAN,MAAqB;AAAA,EAS1B,YAAY,SAAyB,CAAC,GAAG;AACvC,SAAK,OAAO,IAAI,WAAW,MAAM;AACjC,SAAK,eAAe,IAAI,aAAa,OAAO,OAAO;AAEnD,SAAK,OAAO,IAAI;AAAA,MACd,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAEA,SAAK,WAAW,IAAI,SAAS,KAAK,IAAI;AACtC,SAAK,UAAU,IAAI,QAAQ,KAAK,IAAI;AACpC,SAAK,KAAK,IAAI,GAAG,KAAK,IAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,UAAU,QAAsB;AAE9B,SAAK,KAAK,aAAa,MAAM;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,gBAA4B;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUF;;;ARpDO,SAAS,aAAa,QAAwC;AACnE,SAAO,IAAI,eAAe,MAAM;AAClC;AAGA,IAAO,gBAAQ;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/lib/http-client.ts","../src/lib/token-manager.ts","../src/modules/database.ts","../src/modules/auth.ts","../src/modules/storage.ts","../src/client.ts"],"sourcesContent":["/**\n * @insforge/sdk - TypeScript SDK for InsForge Backend-as-a-Service\n * \n * @packageDocumentation\n */\n\n// Main client\nexport { InsForgeClient } from './client';\n\n// Types\nexport type {\n InsForgeConfig,\n InsForgeConfig as ClientOptions, // Alias for compatibility\n TokenStorage,\n AuthSession,\n ApiError,\n} from './types';\n\nexport { InsForgeError } from './types';\n\n// Re-export shared schemas that SDK users will need\nexport type {\n UserSchema,\n CreateUserRequest,\n CreateSessionRequest,\n AuthErrorResponse,\n} from '@insforge/shared-schemas';\n\n// Re-export auth module for advanced usage\nexport { Auth } from './modules/auth';\n\n// Re-export database module and types\nexport { Database, QueryBuilder } from './modules/database';\nexport type { DatabaseResponse } from './modules/database';\n\n// Re-export storage module and types\nexport { Storage, StorageBucket } from './modules/storage';\nexport type { StorageResponse } from './modules/storage';\n\n// Re-export utilities for advanced usage\nexport { HttpClient } from './lib/http-client';\nexport { TokenManager } from './lib/token-manager';\n\n// Factory function for creating clients (Supabase-style)\nimport { InsForgeClient } from './client';\nimport { InsForgeConfig } from './types';\n\nexport function createClient(config: InsForgeConfig): InsForgeClient {\n return new InsForgeClient(config);\n}\n\n// Default export for convenience\nexport default InsForgeClient;","/**\n * InsForge SDK Types - only SDK-specific types here\n * Use @insforge/shared-schemas directly for API types\n */\n\nimport type { UserSchema } from '@insforge/shared-schemas';\n\nexport interface InsForgeConfig {\n /**\n * The base URL of the InsForge backend API\n * @default \"http://localhost:7130\"\n */\n baseUrl?: string;\n\n /**\n * API key (optional)\n * Can be used for server-side operations or specific use cases\n */\n apiKey?: string;\n\n /**\n * Custom fetch implementation (useful for Node.js environments)\n */\n fetch?: typeof fetch;\n\n /**\n * Storage adapter for persisting tokens\n */\n storage?: TokenStorage;\n\n /**\n * Whether to automatically refresh tokens before they expire\n * @default true\n */\n autoRefreshToken?: boolean;\n\n /**\n * Whether to persist session in storage\n * @default true\n */\n persistSession?: boolean;\n\n /**\n * Custom headers to include with every request\n */\n headers?: Record<string, string>;\n}\n\nexport interface TokenStorage {\n getItem(key: string): string | null | Promise<string | null>;\n setItem(key: string, value: string): void | Promise<void>;\n removeItem(key: string): void | Promise<void>;\n}\n\nexport interface AuthSession {\n user: UserSchema;\n accessToken: string;\n expiresAt?: Date;\n}\n\nexport interface ApiError {\n error: string;\n message: string;\n statusCode: number;\n nextActions?: string;\n}\n\nexport class InsForgeError extends Error {\n public statusCode: number;\n public error: string;\n public nextActions?: string;\n\n constructor(message: string, statusCode: number, error: string, nextActions?: string) {\n super(message);\n this.name = 'InsForgeError';\n this.statusCode = statusCode;\n this.error = error;\n this.nextActions = nextActions;\n }\n\n static fromApiError(apiError: ApiError): InsForgeError {\n return new InsForgeError(\n apiError.message,\n apiError.statusCode,\n apiError.error,\n apiError.nextActions\n );\n }\n}","import { InsForgeConfig, ApiError, InsForgeError } from '../types';\n\nexport interface RequestOptions extends RequestInit {\n params?: Record<string, string>;\n}\n\nexport class HttpClient {\n public readonly baseUrl: string;\n public readonly fetch: typeof fetch;\n private defaultHeaders: Record<string, string>;\n\n constructor(config: InsForgeConfig) {\n this.baseUrl = config.baseUrl || 'http://localhost:7130';\n // Properly bind fetch to maintain its context\n this.fetch = config.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined as any);\n this.defaultHeaders = {\n ...config.headers,\n };\n \n // Add API key if provided\n if (config.apiKey) {\n this.defaultHeaders['Authorization'] = `Bearer ${config.apiKey}`;\n }\n\n if (!this.fetch) {\n throw new Error(\n 'Fetch is not available. Please provide a fetch implementation in the config.'\n );\n }\n }\n\n private buildUrl(path: string, params?: Record<string, string>): string {\n const url = new URL(path, this.baseUrl);\n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n // For select parameter, preserve the exact formatting by normalizing whitespace\n // This ensures PostgREST relationship queries work correctly\n if (key === 'select') {\n // Normalize multiline select strings for PostgREST:\n // 1. Replace all whitespace (including newlines) with single space\n // 2. Remove spaces inside parentheses for proper PostgREST syntax\n // 3. Keep spaces after commas at the top level for readability\n let normalizedValue = value.replace(/\\s+/g, ' ').trim();\n \n // Fix spaces around parentheses and inside them\n normalizedValue = normalizedValue\n .replace(/\\s*\\(\\s*/g, '(') // Remove spaces around opening parens\n .replace(/\\s*\\)\\s*/g, ')') // Remove spaces around closing parens\n .replace(/\\(\\s+/g, '(') // Remove spaces after opening parens\n .replace(/\\s+\\)/g, ')') // Remove spaces before closing parens\n .replace(/,\\s+(?=[^()]*\\))/g, ','); // Remove spaces after commas inside parens\n \n url.searchParams.append(key, normalizedValue);\n } else {\n url.searchParams.append(key, value);\n }\n });\n }\n return url.toString();\n }\n\n async request<T>(\n method: string,\n path: string,\n options: RequestOptions = {}\n ): Promise<T> {\n const { params, headers = {}, body, ...fetchOptions } = options;\n \n const url = this.buildUrl(path, params);\n \n const requestHeaders: Record<string, string> = {\n ...this.defaultHeaders,\n };\n \n // Handle body serialization\n let processedBody: any;\n if (body !== undefined) {\n // Check if body is FormData (for file uploads)\n if (typeof FormData !== 'undefined' && body instanceof FormData) {\n // Don't set Content-Type for FormData, let browser set it with boundary\n processedBody = body;\n } else {\n // JSON body\n if (method !== 'GET') {\n requestHeaders['Content-Type'] = 'application/json;charset=UTF-8';\n }\n processedBody = JSON.stringify(body);\n }\n }\n \n Object.assign(requestHeaders, headers);\n \n const response = await this.fetch(url, {\n method,\n headers: requestHeaders,\n body: processedBody,\n ...fetchOptions,\n });\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n // Try to parse JSON response\n let data: any;\n const contentType = response.headers.get('content-type');\n // Check for any JSON content type (including PostgREST's vnd.pgrst.object+json)\n if (contentType?.includes('json')) {\n data = await response.json();\n } else {\n // For non-JSON responses, return text\n data = await response.text();\n }\n\n // Handle errors\n if (!response.ok) {\n if (data && typeof data === 'object' && 'error' in data) {\n throw InsForgeError.fromApiError(data as ApiError);\n }\n throw new InsForgeError(\n `Request failed: ${response.statusText}`,\n response.status,\n 'REQUEST_FAILED'\n );\n }\n\n return data as T;\n }\n\n get<T>(path: string, options?: RequestOptions): Promise<T> {\n return this.request<T>('GET', path, options);\n }\n\n post<T>(path: string, body?: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('POST', path, { ...options, body });\n }\n\n put<T>(path: string, body?: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('PUT', path, { ...options, body });\n }\n\n patch<T>(path: string, body?: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('PATCH', path, { ...options, body });\n }\n\n delete<T>(path: string, options?: RequestOptions): Promise<T> {\n return this.request<T>('DELETE', path, options);\n }\n\n setAuthToken(token: string | null) {\n if (token) {\n this.defaultHeaders['Authorization'] = `Bearer ${token}`;\n } else {\n delete this.defaultHeaders['Authorization'];\n }\n }\n\n getHeaders(): Record<string, string> {\n return { ...this.defaultHeaders };\n }\n}","import { TokenStorage, AuthSession } from '../types';\n\nconst TOKEN_KEY = 'insforge-auth-token';\nconst USER_KEY = 'insforge-auth-user';\n\nexport class TokenManager {\n private storage: TokenStorage;\n\n constructor(storage?: TokenStorage) {\n if (storage) {\n // Use provided storage\n this.storage = storage;\n } else if (typeof window !== 'undefined' && window.localStorage) {\n // Browser: use localStorage\n this.storage = window.localStorage;\n } else {\n // Node.js: use in-memory storage\n const store = new Map<string, string>();\n this.storage = {\n getItem: (key: string) => store.get(key) || null,\n setItem: (key: string, value: string) => { store.set(key, value); },\n removeItem: (key: string) => { store.delete(key); }\n };\n }\n }\n\n saveSession(session: AuthSession): void {\n this.storage.setItem(TOKEN_KEY, session.accessToken);\n this.storage.setItem(USER_KEY, JSON.stringify(session.user));\n }\n\n getSession(): AuthSession | null {\n const token = this.storage.getItem(TOKEN_KEY);\n const userStr = this.storage.getItem(USER_KEY);\n\n if (!token || !userStr) {\n return null;\n }\n\n try {\n const user = JSON.parse(userStr as string);\n return { accessToken: token as string, user };\n } catch {\n this.clearSession();\n return null;\n }\n }\n\n getAccessToken(): string | null {\n const token = this.storage.getItem(TOKEN_KEY);\n return typeof token === 'string' ? token : null;\n }\n\n clearSession(): void {\n this.storage.removeItem(TOKEN_KEY);\n this.storage.removeItem(USER_KEY);\n }\n}","/**\n * Database module for InsForge SDK\n * Supabase-style query builder for PostgREST operations\n */\n\nimport { HttpClient } from '../lib/http-client';\nimport { InsForgeError } from '../types';\n\nexport interface DatabaseResponse<T> {\n data: T | null;\n error: InsForgeError | null;\n count?: number;\n}\n\n/**\n * Query builder for database operations\n * Uses method chaining like Supabase\n */\nexport class QueryBuilder<T = any> {\n private method: 'GET' | 'POST' | 'PATCH' | 'DELETE' = 'GET';\n private headers: Record<string, string> = {};\n private queryParams: Record<string, string> = {};\n private body?: any;\n\n constructor(\n private table: string,\n private http: HttpClient\n ) {}\n\n /**\n * Perform a SELECT query\n * For mutations (insert/update/delete), this enables returning data\n * @param columns - Columns to select (default: '*')\n * @example\n * .select('*')\n * .select('id, title, content')\n * .select('*, users!inner(*)') // Join with users table\n * .select('*, profile:profiles(*)') // Join with alias\n * .insert({ title: 'New' }).select() // Returns inserted data\n */\n select(columns: string = '*'): this {\n // For mutations, add return=representation header\n if (this.method !== 'GET') {\n const existingPrefer = this.headers['Prefer'] || '';\n const preferParts = existingPrefer ? [existingPrefer] : [];\n if (!preferParts.some(p => p.includes('return='))) {\n preferParts.push('return=representation');\n }\n this.headers['Prefer'] = preferParts.join(',');\n }\n \n // Always set the select parameter for GET requests\n // This enables PostgREST joins and nested queries\n if (this.method === 'GET' && columns) {\n this.queryParams.select = columns;\n } else if (columns !== '*') {\n // For mutations, only set if not default\n this.queryParams.select = columns;\n }\n return this;\n }\n\n /**\n * Perform an INSERT\n * @param values - Single object or array of objects\n * @param options - { upsert: true } for upsert behavior\n * @example\n * .insert({ title: 'Hello', content: 'World' }).select()\n * .insert([{ title: 'Post 1' }, { title: 'Post 2' }]).select()\n */\n insert(values: Partial<T> | Partial<T>[], options?: { upsert?: boolean }): this {\n this.method = 'POST';\n this.body = Array.isArray(values) ? values : [values];\n \n if (options?.upsert) {\n this.headers['Prefer'] = 'resolution=merge-duplicates';\n }\n \n return this;\n }\n\n /**\n * Perform an UPDATE\n * @param values - Object with fields to update\n * @example\n * .update({ title: 'Updated Title' }).select()\n */\n update(values: Partial<T>): this {\n this.method = 'PATCH';\n this.body = values;\n return this;\n }\n\n /**\n * Perform a DELETE\n * @example\n * .delete().select()\n */\n delete(): this {\n this.method = 'DELETE';\n return this;\n }\n\n /**\n * Perform an UPSERT\n * @param values - Single object or array of objects\n * @example\n * .upsert({ id: 1, title: 'Hello' })\n */\n upsert(values: Partial<T> | Partial<T>[]): this {\n return this.insert(values, { upsert: true });\n }\n\n // FILTERS\n\n /**\n * Filter by column equal to value\n * @example .eq('id', 123)\n */\n eq(column: string, value: any): this {\n this.queryParams[column] = `eq.${value}`;\n return this;\n }\n\n /**\n * Filter by column not equal to value\n * @example .neq('status', 'draft')\n */\n neq(column: string, value: any): this {\n this.queryParams[column] = `neq.${value}`;\n return this;\n }\n\n /**\n * Filter by column greater than value\n * @example .gt('age', 18)\n */\n gt(column: string, value: any): this {\n this.queryParams[column] = `gt.${value}`;\n return this;\n }\n\n /**\n * Filter by column greater than or equal to value\n * @example .gte('price', 100)\n */\n gte(column: string, value: any): this {\n this.queryParams[column] = `gte.${value}`;\n return this;\n }\n\n /**\n * Filter by column less than value\n * @example .lt('stock', 10)\n */\n lt(column: string, value: any): this {\n this.queryParams[column] = `lt.${value}`;\n return this;\n }\n\n /**\n * Filter by column less than or equal to value\n * @example .lte('discount', 50)\n */\n lte(column: string, value: any): this {\n this.queryParams[column] = `lte.${value}`;\n return this;\n }\n\n /**\n * Filter by pattern matching (case-sensitive)\n * @example .like('email', '%@gmail.com')\n */\n like(column: string, pattern: string): this {\n this.queryParams[column] = `like.${pattern}`;\n return this;\n }\n\n /**\n * Filter by pattern matching (case-insensitive)\n * @example .ilike('name', '%john%')\n */\n ilike(column: string, pattern: string): this {\n this.queryParams[column] = `ilike.${pattern}`;\n return this;\n }\n\n /**\n * Filter by checking if column is a value\n * @example .is('deleted_at', null)\n */\n is(column: string, value: null | boolean): this {\n if (value === null) {\n this.queryParams[column] = 'is.null';\n } else {\n this.queryParams[column] = `is.${value}`;\n }\n return this;\n }\n\n /**\n * Filter by checking if value is in array\n * @example .in('status', ['active', 'pending'])\n */\n in(column: string, values: any[]): this {\n this.queryParams[column] = `in.(${values.join(',')})`;\n return this;\n }\n\n // MODIFIERS\n\n /**\n * Order by column\n * @example \n * .order('created_at') // ascending\n * .order('created_at', { ascending: false }) // descending\n */\n order(column: string, options?: { ascending?: boolean }): this {\n const ascending = options?.ascending !== false;\n this.queryParams.order = ascending ? column : `${column}.desc`;\n return this;\n }\n\n /**\n * Limit the number of rows returned\n * @example .limit(10)\n */\n limit(count: number): this {\n this.queryParams.limit = count.toString();\n return this;\n }\n\n /**\n * Return results from an offset\n * @example .offset(20)\n */\n offset(count: number): this {\n this.queryParams.offset = count.toString();\n return this;\n }\n\n /**\n * Set a range of rows to return\n * @example .range(0, 9) // First 10 rows\n */\n range(from: number, to: number): this {\n this.headers['Range'] = `${from}-${to}`;\n return this;\n }\n\n /**\n * Return a single object instead of array\n * @example .single()\n */\n single(): this {\n this.headers['Accept'] = 'application/vnd.pgrst.object+json';\n return this;\n }\n\n /**\n * Get the total count (use with select)\n * @example .select('*', { count: 'exact' })\n */\n count(algorithm: 'exact' | 'planned' | 'estimated' = 'exact'): this {\n const prefer = this.headers['Prefer'] || '';\n this.headers['Prefer'] = prefer ? `${prefer},count=${algorithm}` : `count=${algorithm}`;\n return this;\n }\n\n /**\n * Execute the query and return results\n */\n async execute(): Promise<DatabaseResponse<T>> {\n try {\n const path = `/api/database/records/${this.table}`;\n let response: any;\n\n switch (this.method) {\n case 'GET':\n response = await this.http.get<T>(path, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n \n case 'POST':\n response = await this.http.post<T>(path, this.body, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n \n case 'PATCH':\n response = await this.http.patch<T>(path, this.body, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n \n case 'DELETE':\n response = await this.http.delete<T>(path, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n }\n\n return { data: response, error: null };\n } catch (error) {\n return {\n data: null,\n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Database operation failed',\n 500,\n 'DATABASE_ERROR'\n )\n };\n }\n }\n\n /**\n * Make QueryBuilder thenable for async/await\n */\n then<TResult1 = DatabaseResponse<T>, TResult2 = never>(\n onfulfilled?: ((value: DatabaseResponse<T>) => TResult1 | PromiseLike<TResult1>) | undefined | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null\n ): Promise<TResult1 | TResult2> {\n return this.execute().then(onfulfilled, onrejected);\n }\n}\n\n/**\n * Database client for InsForge SDK\n * Provides Supabase-style interface\n */\nexport class Database {\n constructor(private http: HttpClient) {}\n\n /**\n * Create a query builder for a table\n * @param table - The table name\n * @example\n * const { data, error } = await client.database\n * .from('posts')\n * .select('*')\n * .eq('user_id', userId)\n * .order('created_at', { ascending: false })\n * .limit(10);\n */\n from<T = any>(table: string): QueryBuilder<T> {\n return new QueryBuilder<T>(table, this.http);\n }\n}","/**\n * Auth module for InsForge SDK\n * Uses shared schemas for type safety\n */\n\nimport { HttpClient } from '../lib/http-client';\nimport { TokenManager } from '../lib/token-manager';\nimport { AuthSession, InsForgeError } from '../types';\nimport { Database } from './database';\n\nimport type {\n CreateUserRequest,\n CreateUserResponse,\n CreateSessionRequest,\n CreateSessionResponse,\n GetCurrentSessionResponse,\n GetOauthUrlResponse,\n} from '@insforge/shared-schemas';\n\nexport class Auth {\n private database: Database;\n \n constructor(\n private http: HttpClient,\n private tokenManager: TokenManager\n ) {\n this.database = new Database(http);\n \n // Auto-detect OAuth callback parameters in the URL\n this.detectOAuthCallback();\n }\n\n /**\n * Automatically detect and handle OAuth callback parameters in the URL\n * This runs on initialization to seamlessly complete the OAuth flow\n * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)\n */\n private detectOAuthCallback(): void {\n // Only run in browser environment\n if (typeof window === 'undefined') return;\n \n try {\n const params = new URLSearchParams(window.location.search);\n \n // Backend returns: access_token, user_id, email, name (optional)\n const accessToken = params.get('access_token');\n const userId = params.get('user_id');\n const email = params.get('email');\n const name = params.get('name');\n \n // Check if we have OAuth callback parameters\n if (accessToken && userId && email) {\n // Create session with the data from backend\n const session: AuthSession = {\n accessToken,\n user: {\n id: userId,\n email: email,\n name: name || '',\n // These fields are not provided by backend OAuth callback\n // They'll be populated when calling getCurrentUser()\n emailVerified: false,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n } as any,\n };\n \n // Save session and set auth token\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(accessToken);\n \n // Clean up the URL to remove sensitive parameters\n const url = new URL(window.location.href);\n url.searchParams.delete('access_token');\n url.searchParams.delete('user_id');\n url.searchParams.delete('email');\n url.searchParams.delete('name');\n \n // Also handle error case from backend (line 581)\n if (params.has('error')) {\n url.searchParams.delete('error');\n }\n \n // Replace URL without adding to browser history\n window.history.replaceState({}, document.title, url.toString());\n }\n } catch (error) {\n // Silently continue - don't break initialization\n console.debug('OAuth callback detection skipped:', error);\n }\n }\n\n /**\n * Sign up a new user\n */\n async signUp(request: CreateUserRequest): Promise<{\n data: CreateUserResponse | null;\n error: InsForgeError | null;\n }> {\n try {\n const response = await this.http.post<CreateUserResponse>('/api/auth/users', request);\n \n // Save session internally\n const session: AuthSession = {\n accessToken: response.accessToken,\n user: response.user,\n };\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(response.accessToken);\n\n return { \n data: response,\n error: null \n };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: null, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: null, \n error: new InsForgeError(\n error instanceof Error ? error.message : 'An unexpected error occurred during sign up',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Sign in with email and password\n */\n async signInWithPassword(request: CreateSessionRequest): Promise<{\n data: CreateSessionResponse | null;\n error: InsForgeError | null;\n }> {\n try {\n const response = await this.http.post<CreateSessionResponse>('/api/auth/sessions', request);\n \n // Save session internally\n const session: AuthSession = {\n accessToken: response.accessToken,\n user: response.user,\n };\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(response.accessToken);\n\n return { \n data: response,\n error: null \n };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: null, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: null, \n error: new InsForgeError(\n 'An unexpected error occurred during sign in',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Sign in with OAuth provider\n */\n async signInWithOAuth(options: {\n provider: 'google' | 'github';\n redirectTo?: string;\n skipBrowserRedirect?: boolean;\n }): Promise<{\n data: { url?: string; provider?: string };\n error: InsForgeError | null;\n }> {\n try {\n const { provider, redirectTo, skipBrowserRedirect } = options;\n \n const params = redirectTo \n ? { redirect_uri: redirectTo } \n : undefined;\n \n const endpoint = `/api/auth/oauth/${provider}`;\n const response = await this.http.get<GetOauthUrlResponse>(endpoint, { params });\n \n // Automatically redirect in browser unless told not to\n if (typeof window !== 'undefined' && !skipBrowserRedirect) {\n window.location.href = response.authUrl;\n return { data: {}, error: null };\n }\n\n return { \n data: { \n url: response.authUrl,\n provider \n }, \n error: null \n };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: {}, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: {}, \n error: new InsForgeError(\n 'An unexpected error occurred during OAuth initialization',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Sign out the current user\n */\n async signOut(): Promise<{ error: InsForgeError | null }> {\n try {\n this.tokenManager.clearSession();\n this.http.setAuthToken(null);\n return { error: null };\n } catch (error) {\n return { \n error: new InsForgeError(\n 'Failed to sign out',\n 500,\n 'SIGNOUT_ERROR'\n )\n };\n }\n }\n\n /**\n * Get the current user with full profile information\n * Returns both auth info (id, email, role) and profile data (nickname, avatar_url, bio, etc.)\n */\n async getCurrentUser(): Promise<{\n data: { user: any; profile: any } | null;\n error: InsForgeError | null;\n }> {\n try {\n // Check if we have a token\n const session = this.tokenManager.getSession();\n if (!session?.accessToken) {\n return { data: null, error: null };\n }\n\n // Call the API for auth info\n this.http.setAuthToken(session.accessToken);\n const authResponse = await this.http.get<GetCurrentSessionResponse>('/api/auth/sessions/current');\n \n // Get the user's profile using query builder\n const { data: profile, error: profileError } = await this.database\n .from('users')\n .select('*')\n .eq('id', authResponse.user.id)\n .single();\n \n if (profileError && profileError.statusCode !== 406) { // 406 = not found\n return { data: null, error: profileError };\n }\n \n return {\n data: {\n user: authResponse.user,\n profile: profile\n },\n error: null\n };\n } catch (error) {\n // If unauthorized, clear session\n if (error instanceof InsForgeError && error.statusCode === 401) {\n await this.signOut();\n return { data: null, error: null };\n }\n \n // Pass through all other errors unchanged\n if (error instanceof InsForgeError) {\n return { data: null, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: null, \n error: new InsForgeError(\n 'An unexpected error occurred while fetching user',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Get any user's profile by ID\n * Returns profile information from the users table (nickname, avatar_url, bio, etc.)\n */\n async getProfile(userId: string): Promise<{\n data: any | null;\n error: InsForgeError | null;\n }> {\n const { data, error } = await this.database\n .from('users')\n .select('*')\n .eq('id', userId)\n .single();\n \n // Handle not found as null, not error\n if (error && error.statusCode === 406) {\n return { data: null, error: null };\n }\n \n return { data, error };\n }\n\n /**\n * Get the current session (only session data, no API call)\n * Returns the stored JWT token and basic user info from local storage\n */\n async getCurrentSession(): Promise<{\n data: { session: AuthSession | null };\n error: InsForgeError | null;\n }> {\n try {\n const session = this.tokenManager.getSession();\n \n if (session?.accessToken) {\n this.http.setAuthToken(session.accessToken);\n return { data: { session }, error: null };\n }\n\n return { data: { session: null }, error: null };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: { session: null }, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: { session: null }, \n error: new InsForgeError(\n 'An unexpected error occurred while getting session',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Set/Update the current user's profile\n * Updates profile information in the users table (nickname, avatar_url, bio, etc.)\n */\n async setProfile(profile: {\n nickname?: string;\n avatar_url?: string;\n bio?: string;\n birthday?: string;\n [key: string]: any;\n }): Promise<{\n data: any | null;\n error: InsForgeError | null;\n }> {\n // Get current session to get user ID\n const session = this.tokenManager.getSession();\n if (!session?.user?.id) {\n return { \n data: null, \n error: new InsForgeError(\n 'No authenticated user found',\n 401,\n 'UNAUTHENTICATED'\n )\n };\n }\n\n // Update the profile using query builder\n return await this.database\n .from('users')\n .update(profile)\n .eq('id', session.user.id)\n .select()\n .single();\n }\n\n\n}","/**\n * Storage module for InsForge SDK\n * Handles file uploads, downloads, and bucket management\n */\n\nimport { HttpClient } from '../lib/http-client';\nimport { InsForgeError } from '../types';\nimport type { \n StorageFileSchema,\n ListObjectsResponseSchema\n} from '@insforge/shared-schemas';\n\nexport interface StorageResponse<T> {\n data: T | null;\n error: InsForgeError | null;\n}\n\n/**\n * Storage bucket operations\n */\nexport class StorageBucket {\n constructor(\n private bucketName: string,\n private http: HttpClient\n ) {}\n\n /**\n * Upload a file with a specific key\n * @param path - The object key/path\n * @param file - File or Blob to upload\n */\n async upload(\n path: string,\n file: File | Blob\n ): Promise<StorageResponse<StorageFileSchema>> {\n try {\n const formData = new FormData();\n formData.append('file', file);\n\n // Use PUT for specific path\n const response = await this.http.request<StorageFileSchema>(\n 'PUT',\n `/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`,\n {\n body: formData as any,\n headers: {\n // Don't set Content-Type, let browser set multipart boundary\n }\n }\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Upload failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Upload a file with auto-generated key\n * @param file - File or Blob to upload\n */\n async uploadAuto(\n file: File | Blob\n ): Promise<StorageResponse<StorageFileSchema>> {\n try {\n const formData = new FormData();\n formData.append('file', file);\n\n // Use POST for auto-generated key\n const response = await this.http.request<StorageFileSchema>(\n 'POST',\n `/api/storage/buckets/${this.bucketName}/objects`,\n {\n body: formData as any,\n headers: {\n // Don't set Content-Type, let browser set multipart boundary\n }\n }\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Upload failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Download a file\n * @param path - The object key/path\n * Returns the file as a Blob\n */\n async download(path: string): Promise<{ data: Blob | null; error: InsForgeError | null }> {\n try {\n // For binary data, we need to use fetch directly with proper response handling\n // The http.request method expects JSON responses, so we can't use it for blobs\n const url = `${this.http.baseUrl}/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`;\n \n const response = await this.http.fetch(url, {\n method: 'GET',\n headers: this.http.getHeaders()\n });\n\n if (!response.ok) {\n try {\n const error = await response.json();\n throw InsForgeError.fromApiError(error);\n } catch {\n throw new InsForgeError(\n `Download failed: ${response.statusText}`,\n response.status,\n 'STORAGE_ERROR'\n );\n }\n }\n\n const blob = await response.blob();\n return { data: blob, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Download failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Get public URL for a file\n * @param path - The object key/path\n */\n getPublicUrl(path: string): string {\n return `${this.http.baseUrl}/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`;\n }\n\n /**\n * List objects in the bucket\n * @param prefix - Filter by key prefix\n * @param search - Search in file names\n * @param limit - Maximum number of results (default: 100, max: 1000)\n * @param offset - Number of results to skip\n */\n async list(options?: {\n prefix?: string;\n search?: string;\n limit?: number;\n offset?: number;\n }): Promise<StorageResponse<ListObjectsResponseSchema>> {\n try {\n const params: Record<string, string> = {};\n \n if (options?.prefix) params.prefix = options.prefix;\n if (options?.search) params.search = options.search;\n if (options?.limit) params.limit = options.limit.toString();\n if (options?.offset) params.offset = options.offset.toString();\n\n const response = await this.http.get<ListObjectsResponseSchema>(\n `/api/storage/buckets/${this.bucketName}/objects`,\n { params }\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'List failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Delete a file\n * @param path - The object key/path\n */\n async remove(path: string): Promise<StorageResponse<{ message: string }>> {\n try {\n const response = await this.http.delete<{ message: string }>(\n `/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Delete failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n}\n\n/**\n * Storage module for file operations\n */\nexport class Storage {\n constructor(private http: HttpClient) {}\n\n /**\n * Get a bucket instance for operations\n * @param bucketName - Name of the bucket\n */\n from(bucketName: string): StorageBucket {\n return new StorageBucket(bucketName, this.http);\n }\n}","import { InsForgeConfig } from './types';\nimport { HttpClient } from './lib/http-client';\nimport { TokenManager } from './lib/token-manager';\nimport { Auth } from './modules/auth';\nimport { Database } from './modules/database';\nimport { Storage } from './modules/storage';\n\n/**\n * Main InsForge SDK Client\n * \n * @example\n * ```typescript\n * import { InsForgeClient } from '@insforge/sdk';\n * \n * const client = new InsForgeClient({\n * baseUrl: 'http://localhost:7130'\n * });\n * \n * // Authentication\n * const session = await client.auth.register({\n * email: 'user@example.com',\n * password: 'password123',\n * name: 'John Doe'\n * });\n * \n * // Database operations\n * const { data, error } = await client.database\n * .from('posts')\n * .select('*')\n * .eq('user_id', session.user.id)\n * .order('created_at', { ascending: false })\n * .limit(10);\n * \n * // Insert data\n * const { data: newPost } = await client.database\n * .from('posts')\n * .insert({ title: 'Hello', content: 'World' })\n * .single();\n * ```\n */\nexport class InsForgeClient {\n private http: HttpClient;\n private tokenManager: TokenManager;\n \n public readonly auth: Auth;\n public readonly database: Database;\n public readonly storage: Storage;\n\n constructor(config: InsForgeConfig = {}) {\n this.http = new HttpClient(config);\n this.tokenManager = new TokenManager(config.storage);\n \n this.auth = new Auth(\n this.http,\n this.tokenManager\n );\n \n this.database = new Database(this.http);\n this.storage = new Storage(this.http);\n }\n\n\n /**\n * Set a custom API key for authentication\n * This is useful for server-to-server communication\n * \n * @param apiKey - The API key (should start with 'ik_')\n * \n * @example\n * ```typescript\n * client.setApiKey('ik_your_api_key_here');\n * ```\n */\n setApiKey(apiKey: string): void {\n // API keys can be used as Bearer tokens\n this.http.setAuthToken(apiKey);\n }\n\n /**\n * Get the underlying HTTP client for custom requests\n * \n * @example\n * ```typescript\n * const httpClient = client.getHttpClient();\n * const customData = await httpClient.get('/api/custom-endpoint');\n * ```\n */\n getHttpClient(): HttpClient {\n return this.http;\n }\n\n /**\n * Future modules will be added here:\n * - database: Database operations\n * - storage: File storage operations\n * - functions: Serverless functions\n * - tables: Table management\n * - metadata: Backend metadata\n */\n}"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -39,7 +39,8 @@ var HttpClient = class {
39
39
  if (params) {
40
40
  Object.entries(params).forEach(([key, value]) => {
41
41
  if (key === "select") {
42
- const normalizedValue = value.replace(/\s+/g, " ").trim();
42
+ let normalizedValue = value.replace(/\s+/g, " ").trim();
43
+ normalizedValue = normalizedValue.replace(/\s*\(\s*/g, "(").replace(/\s*\)\s*/g, ")").replace(/\(\s+/g, "(").replace(/\s+\)/g, ")").replace(/,\s+(?=[^()]*\))/g, ",");
43
44
  url.searchParams.append(key, normalizedValue);
44
45
  } else {
45
46
  url.searchParams.append(key, value);
@@ -899,133 +900,6 @@ var Storage = class {
899
900
  }
900
901
  };
901
902
 
902
- // src/modules/ai.ts
903
- var AI = class {
904
- constructor(http) {
905
- this.http = http;
906
- this.chat = new Chat(http);
907
- this.images = new Images(http);
908
- }
909
- };
910
- var Chat = class {
911
- constructor(http) {
912
- this.completions = new ChatCompletions(http);
913
- }
914
- };
915
- var ChatCompletions = class {
916
- constructor(http) {
917
- this.http = http;
918
- }
919
- /**
920
- * Create a chat completion
921
- *
922
- * @example
923
- * ```typescript
924
- * // Non-streaming
925
- * const response = await client.ai.chat.completions.create({
926
- * model: 'gpt-4',
927
- * messages: [{ role: 'user', content: 'Hello!' }]
928
- * });
929
- * console.log(response.response);
930
- *
931
- * // Streaming - returns async iterable
932
- * const stream = await client.ai.chat.completions.create({
933
- * model: 'gpt-4',
934
- * messages: [{ role: 'user', content: 'Tell me a story' }],
935
- * stream: true
936
- * });
937
- *
938
- * for await (const event of stream) {
939
- * if (event.chunk) {
940
- * process.stdout.write(event.chunk);
941
- * }
942
- * if (event.done) {
943
- * console.log('Stream complete!');
944
- * }
945
- * }
946
- * ```
947
- */
948
- async create(params) {
949
- if (params.stream) {
950
- const headers = this.http.getHeaders();
951
- headers["Content-Type"] = "application/json";
952
- const response = await this.http.fetch(
953
- `${this.http.baseUrl}/api/ai/chat`,
954
- {
955
- method: "POST",
956
- headers,
957
- body: JSON.stringify(params)
958
- }
959
- );
960
- if (!response.ok) {
961
- const error = await response.json();
962
- throw new Error(error.error || "Stream request failed");
963
- }
964
- return this.parseSSEStream(response);
965
- }
966
- return this.http.post("/api/ai/chat", params);
967
- }
968
- /**
969
- * Parse SSE stream into async iterable of parsed events
970
- * Users don't need to handle SSE parsing themselves
971
- */
972
- async *parseSSEStream(response) {
973
- const reader = response.body.getReader();
974
- const decoder = new TextDecoder();
975
- let buffer = "";
976
- try {
977
- while (true) {
978
- const { done, value } = await reader.read();
979
- if (done) break;
980
- buffer += decoder.decode(value, { stream: true });
981
- const lines = buffer.split("\n");
982
- buffer = lines.pop() || "";
983
- for (const line of lines) {
984
- if (line.startsWith("data: ")) {
985
- const dataStr = line.slice(6).trim();
986
- if (dataStr) {
987
- try {
988
- const data = JSON.parse(dataStr);
989
- yield data;
990
- if (data.done) {
991
- reader.releaseLock();
992
- return;
993
- }
994
- } catch (e) {
995
- console.warn("Failed to parse SSE data:", dataStr);
996
- }
997
- }
998
- }
999
- }
1000
- }
1001
- } finally {
1002
- reader.releaseLock();
1003
- }
1004
- }
1005
- };
1006
- var Images = class {
1007
- constructor(http) {
1008
- this.http = http;
1009
- }
1010
- /**
1011
- * Generate images
1012
- *
1013
- * @example
1014
- * ```typescript
1015
- * const response = await client.ai.images.generate({
1016
- * model: 'dall-e-3',
1017
- * prompt: 'A sunset over mountains',
1018
- * numImages: 1,
1019
- * size: '1024x1024'
1020
- * });
1021
- * console.log(response.images[0].url);
1022
- * ```
1023
- */
1024
- async generate(params) {
1025
- return this.http.post("/api/ai/image/generation", params);
1026
- }
1027
- };
1028
-
1029
903
  // src/client.ts
1030
904
  var InsForgeClient = class {
1031
905
  constructor(config = {}) {
@@ -1037,7 +911,6 @@ var InsForgeClient = class {
1037
911
  );
1038
912
  this.database = new Database(this.http);
1039
913
  this.storage = new Storage(this.http);
1040
- this.ai = new AI(this.http);
1041
914
  }
1042
915
  /**
1043
916
  * Set a custom API key for authentication
@@ -1081,7 +954,6 @@ function createClient(config) {
1081
954
  }
1082
955
  var index_default = InsForgeClient;
1083
956
  export {
1084
- AI,
1085
957
  Auth,
1086
958
  Database,
1087
959
  HttpClient,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/lib/http-client.ts","../src/lib/token-manager.ts","../src/modules/database.ts","../src/modules/auth.ts","../src/modules/storage.ts","../src/modules/ai.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["/**\n * InsForge SDK Types - only SDK-specific types here\n * Use @insforge/shared-schemas directly for API types\n */\n\nimport type { UserSchema } from '@insforge/shared-schemas';\n\nexport interface InsForgeConfig {\n /**\n * The base URL of the InsForge backend API\n * @default \"http://localhost:7130\"\n */\n baseUrl?: string;\n\n /**\n * API key (optional)\n * Can be used for server-side operations or specific use cases\n */\n apiKey?: string;\n\n /**\n * Custom fetch implementation (useful for Node.js environments)\n */\n fetch?: typeof fetch;\n\n /**\n * Storage adapter for persisting tokens\n */\n storage?: TokenStorage;\n\n /**\n * Whether to automatically refresh tokens before they expire\n * @default true\n */\n autoRefreshToken?: boolean;\n\n /**\n * Whether to persist session in storage\n * @default true\n */\n persistSession?: boolean;\n\n /**\n * Custom headers to include with every request\n */\n headers?: Record<string, string>;\n}\n\nexport interface TokenStorage {\n getItem(key: string): string | null | Promise<string | null>;\n setItem(key: string, value: string): void | Promise<void>;\n removeItem(key: string): void | Promise<void>;\n}\n\nexport interface AuthSession {\n user: UserSchema;\n accessToken: string;\n expiresAt?: Date;\n}\n\nexport interface ApiError {\n error: string;\n message: string;\n statusCode: number;\n nextActions?: string;\n}\n\nexport class InsForgeError extends Error {\n public statusCode: number;\n public error: string;\n public nextActions?: string;\n\n constructor(message: string, statusCode: number, error: string, nextActions?: string) {\n super(message);\n this.name = 'InsForgeError';\n this.statusCode = statusCode;\n this.error = error;\n this.nextActions = nextActions;\n }\n\n static fromApiError(apiError: ApiError): InsForgeError {\n return new InsForgeError(\n apiError.message,\n apiError.statusCode,\n apiError.error,\n apiError.nextActions\n );\n }\n}","import { InsForgeConfig, ApiError, InsForgeError } from '../types';\n\nexport interface RequestOptions extends RequestInit {\n params?: Record<string, string>;\n}\n\nexport class HttpClient {\n public readonly baseUrl: string;\n public readonly fetch: typeof fetch;\n private defaultHeaders: Record<string, string>;\n\n constructor(config: InsForgeConfig) {\n this.baseUrl = config.baseUrl || 'http://localhost:7130';\n // Properly bind fetch to maintain its context\n this.fetch = config.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined as any);\n this.defaultHeaders = {\n ...config.headers,\n };\n \n // Add API key if provided\n if (config.apiKey) {\n this.defaultHeaders['Authorization'] = `Bearer ${config.apiKey}`;\n }\n\n if (!this.fetch) {\n throw new Error(\n 'Fetch is not available. Please provide a fetch implementation in the config.'\n );\n }\n }\n\n private buildUrl(path: string, params?: Record<string, string>): string {\n const url = new URL(path, this.baseUrl);\n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n // For select parameter, preserve the exact formatting by normalizing whitespace\n // This ensures PostgREST relationship queries work correctly\n if (key === 'select') {\n // Normalize multiline select strings: remove extra whitespace but preserve structure\n const normalizedValue = value.replace(/\\s+/g, ' ').trim();\n url.searchParams.append(key, normalizedValue);\n } else {\n url.searchParams.append(key, value);\n }\n });\n }\n return url.toString();\n }\n\n async request<T>(\n method: string,\n path: string,\n options: RequestOptions = {}\n ): Promise<T> {\n const { params, headers = {}, body, ...fetchOptions } = options;\n \n const url = this.buildUrl(path, params);\n \n const requestHeaders: Record<string, string> = {\n ...this.defaultHeaders,\n };\n \n // Handle body serialization\n let processedBody: any;\n if (body !== undefined) {\n // Check if body is FormData (for file uploads)\n if (typeof FormData !== 'undefined' && body instanceof FormData) {\n // Don't set Content-Type for FormData, let browser set it with boundary\n processedBody = body;\n } else {\n // JSON body\n if (method !== 'GET') {\n requestHeaders['Content-Type'] = 'application/json;charset=UTF-8';\n }\n processedBody = JSON.stringify(body);\n }\n }\n \n Object.assign(requestHeaders, headers);\n \n const response = await this.fetch(url, {\n method,\n headers: requestHeaders,\n body: processedBody,\n ...fetchOptions,\n });\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n // Try to parse JSON response\n let data: any;\n const contentType = response.headers.get('content-type');\n // Check for any JSON content type (including PostgREST's vnd.pgrst.object+json)\n if (contentType?.includes('json')) {\n data = await response.json();\n } else {\n // For non-JSON responses, return text\n data = await response.text();\n }\n\n // Handle errors\n if (!response.ok) {\n if (data && typeof data === 'object' && 'error' in data) {\n throw InsForgeError.fromApiError(data as ApiError);\n }\n throw new InsForgeError(\n `Request failed: ${response.statusText}`,\n response.status,\n 'REQUEST_FAILED'\n );\n }\n\n return data as T;\n }\n\n get<T>(path: string, options?: RequestOptions): Promise<T> {\n return this.request<T>('GET', path, options);\n }\n\n post<T>(path: string, body?: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('POST', path, { ...options, body });\n }\n\n put<T>(path: string, body?: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('PUT', path, { ...options, body });\n }\n\n patch<T>(path: string, body?: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('PATCH', path, { ...options, body });\n }\n\n delete<T>(path: string, options?: RequestOptions): Promise<T> {\n return this.request<T>('DELETE', path, options);\n }\n\n setAuthToken(token: string | null) {\n if (token) {\n this.defaultHeaders['Authorization'] = `Bearer ${token}`;\n } else {\n delete this.defaultHeaders['Authorization'];\n }\n }\n\n getHeaders(): Record<string, string> {\n return { ...this.defaultHeaders };\n }\n}","import { TokenStorage, AuthSession } from '../types';\n\nconst TOKEN_KEY = 'insforge-auth-token';\nconst USER_KEY = 'insforge-auth-user';\n\nexport class TokenManager {\n private storage: TokenStorage;\n\n constructor(storage?: TokenStorage) {\n if (storage) {\n // Use provided storage\n this.storage = storage;\n } else if (typeof window !== 'undefined' && window.localStorage) {\n // Browser: use localStorage\n this.storage = window.localStorage;\n } else {\n // Node.js: use in-memory storage\n const store = new Map<string, string>();\n this.storage = {\n getItem: (key: string) => store.get(key) || null,\n setItem: (key: string, value: string) => { store.set(key, value); },\n removeItem: (key: string) => { store.delete(key); }\n };\n }\n }\n\n saveSession(session: AuthSession): void {\n this.storage.setItem(TOKEN_KEY, session.accessToken);\n this.storage.setItem(USER_KEY, JSON.stringify(session.user));\n }\n\n getSession(): AuthSession | null {\n const token = this.storage.getItem(TOKEN_KEY);\n const userStr = this.storage.getItem(USER_KEY);\n\n if (!token || !userStr) {\n return null;\n }\n\n try {\n const user = JSON.parse(userStr as string);\n return { accessToken: token as string, user };\n } catch {\n this.clearSession();\n return null;\n }\n }\n\n getAccessToken(): string | null {\n const token = this.storage.getItem(TOKEN_KEY);\n return typeof token === 'string' ? token : null;\n }\n\n clearSession(): void {\n this.storage.removeItem(TOKEN_KEY);\n this.storage.removeItem(USER_KEY);\n }\n}","/**\n * Database module for InsForge SDK\n * Supabase-style query builder for PostgREST operations\n */\n\nimport { HttpClient } from '../lib/http-client';\nimport { InsForgeError } from '../types';\n\nexport interface DatabaseResponse<T> {\n data: T | null;\n error: InsForgeError | null;\n count?: number;\n}\n\n/**\n * Query builder for database operations\n * Uses method chaining like Supabase\n */\nexport class QueryBuilder<T = any> {\n private method: 'GET' | 'POST' | 'PATCH' | 'DELETE' = 'GET';\n private headers: Record<string, string> = {};\n private queryParams: Record<string, string> = {};\n private body?: any;\n\n constructor(\n private table: string,\n private http: HttpClient\n ) {}\n\n /**\n * Perform a SELECT query\n * For mutations (insert/update/delete), this enables returning data\n * @param columns - Columns to select (default: '*')\n * @example\n * .select('*')\n * .select('id, title, content')\n * .select('*, users!inner(*)') // Join with users table\n * .select('*, profile:profiles(*)') // Join with alias\n * .insert({ title: 'New' }).select() // Returns inserted data\n */\n select(columns: string = '*'): this {\n // For mutations, add return=representation header\n if (this.method !== 'GET') {\n const existingPrefer = this.headers['Prefer'] || '';\n const preferParts = existingPrefer ? [existingPrefer] : [];\n if (!preferParts.some(p => p.includes('return='))) {\n preferParts.push('return=representation');\n }\n this.headers['Prefer'] = preferParts.join(',');\n }\n \n // Always set the select parameter for GET requests\n // This enables PostgREST joins and nested queries\n if (this.method === 'GET' && columns) {\n this.queryParams.select = columns;\n } else if (columns !== '*') {\n // For mutations, only set if not default\n this.queryParams.select = columns;\n }\n return this;\n }\n\n /**\n * Perform an INSERT\n * @param values - Single object or array of objects\n * @param options - { upsert: true } for upsert behavior\n * @example\n * .insert({ title: 'Hello', content: 'World' }).select()\n * .insert([{ title: 'Post 1' }, { title: 'Post 2' }]).select()\n */\n insert(values: Partial<T> | Partial<T>[], options?: { upsert?: boolean }): this {\n this.method = 'POST';\n this.body = Array.isArray(values) ? values : [values];\n \n if (options?.upsert) {\n this.headers['Prefer'] = 'resolution=merge-duplicates';\n }\n \n return this;\n }\n\n /**\n * Perform an UPDATE\n * @param values - Object with fields to update\n * @example\n * .update({ title: 'Updated Title' }).select()\n */\n update(values: Partial<T>): this {\n this.method = 'PATCH';\n this.body = values;\n return this;\n }\n\n /**\n * Perform a DELETE\n * @example\n * .delete().select()\n */\n delete(): this {\n this.method = 'DELETE';\n return this;\n }\n\n /**\n * Perform an UPSERT\n * @param values - Single object or array of objects\n * @example\n * .upsert({ id: 1, title: 'Hello' })\n */\n upsert(values: Partial<T> | Partial<T>[]): this {\n return this.insert(values, { upsert: true });\n }\n\n // FILTERS\n\n /**\n * Filter by column equal to value\n * @example .eq('id', 123)\n */\n eq(column: string, value: any): this {\n this.queryParams[column] = `eq.${value}`;\n return this;\n }\n\n /**\n * Filter by column not equal to value\n * @example .neq('status', 'draft')\n */\n neq(column: string, value: any): this {\n this.queryParams[column] = `neq.${value}`;\n return this;\n }\n\n /**\n * Filter by column greater than value\n * @example .gt('age', 18)\n */\n gt(column: string, value: any): this {\n this.queryParams[column] = `gt.${value}`;\n return this;\n }\n\n /**\n * Filter by column greater than or equal to value\n * @example .gte('price', 100)\n */\n gte(column: string, value: any): this {\n this.queryParams[column] = `gte.${value}`;\n return this;\n }\n\n /**\n * Filter by column less than value\n * @example .lt('stock', 10)\n */\n lt(column: string, value: any): this {\n this.queryParams[column] = `lt.${value}`;\n return this;\n }\n\n /**\n * Filter by column less than or equal to value\n * @example .lte('discount', 50)\n */\n lte(column: string, value: any): this {\n this.queryParams[column] = `lte.${value}`;\n return this;\n }\n\n /**\n * Filter by pattern matching (case-sensitive)\n * @example .like('email', '%@gmail.com')\n */\n like(column: string, pattern: string): this {\n this.queryParams[column] = `like.${pattern}`;\n return this;\n }\n\n /**\n * Filter by pattern matching (case-insensitive)\n * @example .ilike('name', '%john%')\n */\n ilike(column: string, pattern: string): this {\n this.queryParams[column] = `ilike.${pattern}`;\n return this;\n }\n\n /**\n * Filter by checking if column is a value\n * @example .is('deleted_at', null)\n */\n is(column: string, value: null | boolean): this {\n if (value === null) {\n this.queryParams[column] = 'is.null';\n } else {\n this.queryParams[column] = `is.${value}`;\n }\n return this;\n }\n\n /**\n * Filter by checking if value is in array\n * @example .in('status', ['active', 'pending'])\n */\n in(column: string, values: any[]): this {\n this.queryParams[column] = `in.(${values.join(',')})`;\n return this;\n }\n\n // MODIFIERS\n\n /**\n * Order by column\n * @example \n * .order('created_at') // ascending\n * .order('created_at', { ascending: false }) // descending\n */\n order(column: string, options?: { ascending?: boolean }): this {\n const ascending = options?.ascending !== false;\n this.queryParams.order = ascending ? column : `${column}.desc`;\n return this;\n }\n\n /**\n * Limit the number of rows returned\n * @example .limit(10)\n */\n limit(count: number): this {\n this.queryParams.limit = count.toString();\n return this;\n }\n\n /**\n * Return results from an offset\n * @example .offset(20)\n */\n offset(count: number): this {\n this.queryParams.offset = count.toString();\n return this;\n }\n\n /**\n * Set a range of rows to return\n * @example .range(0, 9) // First 10 rows\n */\n range(from: number, to: number): this {\n this.headers['Range'] = `${from}-${to}`;\n return this;\n }\n\n /**\n * Return a single object instead of array\n * @example .single()\n */\n single(): this {\n this.headers['Accept'] = 'application/vnd.pgrst.object+json';\n return this;\n }\n\n /**\n * Get the total count (use with select)\n * @example .select('*', { count: 'exact' })\n */\n count(algorithm: 'exact' | 'planned' | 'estimated' = 'exact'): this {\n const prefer = this.headers['Prefer'] || '';\n this.headers['Prefer'] = prefer ? `${prefer},count=${algorithm}` : `count=${algorithm}`;\n return this;\n }\n\n /**\n * Execute the query and return results\n */\n async execute(): Promise<DatabaseResponse<T>> {\n try {\n const path = `/api/database/records/${this.table}`;\n let response: any;\n\n switch (this.method) {\n case 'GET':\n response = await this.http.get<T>(path, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n \n case 'POST':\n response = await this.http.post<T>(path, this.body, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n \n case 'PATCH':\n response = await this.http.patch<T>(path, this.body, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n \n case 'DELETE':\n response = await this.http.delete<T>(path, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n }\n\n return { data: response, error: null };\n } catch (error) {\n return {\n data: null,\n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Database operation failed',\n 500,\n 'DATABASE_ERROR'\n )\n };\n }\n }\n\n /**\n * Make QueryBuilder thenable for async/await\n */\n then<TResult1 = DatabaseResponse<T>, TResult2 = never>(\n onfulfilled?: ((value: DatabaseResponse<T>) => TResult1 | PromiseLike<TResult1>) | undefined | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null\n ): Promise<TResult1 | TResult2> {\n return this.execute().then(onfulfilled, onrejected);\n }\n}\n\n/**\n * Database client for InsForge SDK\n * Provides Supabase-style interface\n */\nexport class Database {\n constructor(private http: HttpClient) {}\n\n /**\n * Create a query builder for a table\n * @param table - The table name\n * @example\n * const { data, error } = await client.database\n * .from('posts')\n * .select('*')\n * .eq('user_id', userId)\n * .order('created_at', { ascending: false })\n * .limit(10);\n */\n from<T = any>(table: string): QueryBuilder<T> {\n return new QueryBuilder<T>(table, this.http);\n }\n}","/**\n * Auth module for InsForge SDK\n * Uses shared schemas for type safety\n */\n\nimport { HttpClient } from '../lib/http-client';\nimport { TokenManager } from '../lib/token-manager';\nimport { AuthSession, InsForgeError } from '../types';\nimport { Database } from './database';\n\nimport type {\n CreateUserRequest,\n CreateUserResponse,\n CreateSessionRequest,\n CreateSessionResponse,\n GetCurrentSessionResponse,\n GetOauthUrlResponse,\n} from '@insforge/shared-schemas';\n\nexport class Auth {\n private database: Database;\n \n constructor(\n private http: HttpClient,\n private tokenManager: TokenManager\n ) {\n this.database = new Database(http);\n \n // Auto-detect OAuth callback parameters in the URL\n this.detectOAuthCallback();\n }\n\n /**\n * Automatically detect and handle OAuth callback parameters in the URL\n * This runs on initialization to seamlessly complete the OAuth flow\n * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)\n */\n private detectOAuthCallback(): void {\n // Only run in browser environment\n if (typeof window === 'undefined') return;\n \n try {\n const params = new URLSearchParams(window.location.search);\n \n // Backend returns: access_token, user_id, email, name (optional)\n const accessToken = params.get('access_token');\n const userId = params.get('user_id');\n const email = params.get('email');\n const name = params.get('name');\n \n // Check if we have OAuth callback parameters\n if (accessToken && userId && email) {\n // Create session with the data from backend\n const session: AuthSession = {\n accessToken,\n user: {\n id: userId,\n email: email,\n name: name || '',\n // These fields are not provided by backend OAuth callback\n // They'll be populated when calling getCurrentUser()\n emailVerified: false,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n } as any,\n };\n \n // Save session and set auth token\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(accessToken);\n \n // Clean up the URL to remove sensitive parameters\n const url = new URL(window.location.href);\n url.searchParams.delete('access_token');\n url.searchParams.delete('user_id');\n url.searchParams.delete('email');\n url.searchParams.delete('name');\n \n // Also handle error case from backend (line 581)\n if (params.has('error')) {\n url.searchParams.delete('error');\n }\n \n // Replace URL without adding to browser history\n window.history.replaceState({}, document.title, url.toString());\n }\n } catch (error) {\n // Silently continue - don't break initialization\n console.debug('OAuth callback detection skipped:', error);\n }\n }\n\n /**\n * Sign up a new user\n */\n async signUp(request: CreateUserRequest): Promise<{\n data: CreateUserResponse | null;\n error: InsForgeError | null;\n }> {\n try {\n const response = await this.http.post<CreateUserResponse>('/api/auth/users', request);\n \n // Save session internally\n const session: AuthSession = {\n accessToken: response.accessToken,\n user: response.user,\n };\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(response.accessToken);\n\n return { \n data: response,\n error: null \n };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: null, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: null, \n error: new InsForgeError(\n error instanceof Error ? error.message : 'An unexpected error occurred during sign up',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Sign in with email and password\n */\n async signInWithPassword(request: CreateSessionRequest): Promise<{\n data: CreateSessionResponse | null;\n error: InsForgeError | null;\n }> {\n try {\n const response = await this.http.post<CreateSessionResponse>('/api/auth/sessions', request);\n \n // Save session internally\n const session: AuthSession = {\n accessToken: response.accessToken,\n user: response.user,\n };\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(response.accessToken);\n\n return { \n data: response,\n error: null \n };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: null, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: null, \n error: new InsForgeError(\n 'An unexpected error occurred during sign in',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Sign in with OAuth provider\n */\n async signInWithOAuth(options: {\n provider: 'google' | 'github';\n redirectTo?: string;\n skipBrowserRedirect?: boolean;\n }): Promise<{\n data: { url?: string; provider?: string };\n error: InsForgeError | null;\n }> {\n try {\n const { provider, redirectTo, skipBrowserRedirect } = options;\n \n const params = redirectTo \n ? { redirect_uri: redirectTo } \n : undefined;\n \n const endpoint = `/api/auth/oauth/${provider}`;\n const response = await this.http.get<GetOauthUrlResponse>(endpoint, { params });\n \n // Automatically redirect in browser unless told not to\n if (typeof window !== 'undefined' && !skipBrowserRedirect) {\n window.location.href = response.authUrl;\n return { data: {}, error: null };\n }\n\n return { \n data: { \n url: response.authUrl,\n provider \n }, \n error: null \n };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: {}, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: {}, \n error: new InsForgeError(\n 'An unexpected error occurred during OAuth initialization',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Sign out the current user\n */\n async signOut(): Promise<{ error: InsForgeError | null }> {\n try {\n this.tokenManager.clearSession();\n this.http.setAuthToken(null);\n return { error: null };\n } catch (error) {\n return { \n error: new InsForgeError(\n 'Failed to sign out',\n 500,\n 'SIGNOUT_ERROR'\n )\n };\n }\n }\n\n /**\n * Get the current user with full profile information\n * Returns both auth info (id, email, role) and profile data (nickname, avatar_url, bio, etc.)\n */\n async getCurrentUser(): Promise<{\n data: { user: any; profile: any } | null;\n error: InsForgeError | null;\n }> {\n try {\n // Check if we have a token\n const session = this.tokenManager.getSession();\n if (!session?.accessToken) {\n return { data: null, error: null };\n }\n\n // Call the API for auth info\n this.http.setAuthToken(session.accessToken);\n const authResponse = await this.http.get<GetCurrentSessionResponse>('/api/auth/sessions/current');\n \n // Get the user's profile using query builder\n const { data: profile, error: profileError } = await this.database\n .from('users')\n .select('*')\n .eq('id', authResponse.user.id)\n .single();\n \n if (profileError && profileError.statusCode !== 406) { // 406 = not found\n return { data: null, error: profileError };\n }\n \n return {\n data: {\n user: authResponse.user,\n profile: profile\n },\n error: null\n };\n } catch (error) {\n // If unauthorized, clear session\n if (error instanceof InsForgeError && error.statusCode === 401) {\n await this.signOut();\n return { data: null, error: null };\n }\n \n // Pass through all other errors unchanged\n if (error instanceof InsForgeError) {\n return { data: null, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: null, \n error: new InsForgeError(\n 'An unexpected error occurred while fetching user',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Get any user's profile by ID\n * Returns profile information from the users table (nickname, avatar_url, bio, etc.)\n */\n async getProfile(userId: string): Promise<{\n data: any | null;\n error: InsForgeError | null;\n }> {\n const { data, error } = await this.database\n .from('users')\n .select('*')\n .eq('id', userId)\n .single();\n \n // Handle not found as null, not error\n if (error && error.statusCode === 406) {\n return { data: null, error: null };\n }\n \n return { data, error };\n }\n\n /**\n * Get the current session (only session data, no API call)\n * Returns the stored JWT token and basic user info from local storage\n */\n async getCurrentSession(): Promise<{\n data: { session: AuthSession | null };\n error: InsForgeError | null;\n }> {\n try {\n const session = this.tokenManager.getSession();\n \n if (session?.accessToken) {\n this.http.setAuthToken(session.accessToken);\n return { data: { session }, error: null };\n }\n\n return { data: { session: null }, error: null };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: { session: null }, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: { session: null }, \n error: new InsForgeError(\n 'An unexpected error occurred while getting session',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Set/Update the current user's profile\n * Updates profile information in the users table (nickname, avatar_url, bio, etc.)\n */\n async setProfile(profile: {\n nickname?: string;\n avatar_url?: string;\n bio?: string;\n birthday?: string;\n [key: string]: any;\n }): Promise<{\n data: any | null;\n error: InsForgeError | null;\n }> {\n // Get current session to get user ID\n const session = this.tokenManager.getSession();\n if (!session?.user?.id) {\n return { \n data: null, \n error: new InsForgeError(\n 'No authenticated user found',\n 401,\n 'UNAUTHENTICATED'\n )\n };\n }\n\n // Update the profile using query builder\n return await this.database\n .from('users')\n .update(profile)\n .eq('id', session.user.id)\n .select()\n .single();\n }\n\n\n}","/**\n * Storage module for InsForge SDK\n * Handles file uploads, downloads, and bucket management\n */\n\nimport { HttpClient } from '../lib/http-client';\nimport { InsForgeError } from '../types';\nimport type { \n StorageFileSchema,\n ListObjectsResponseSchema\n} from '@insforge/shared-schemas';\n\nexport interface StorageResponse<T> {\n data: T | null;\n error: InsForgeError | null;\n}\n\n/**\n * Storage bucket operations\n */\nexport class StorageBucket {\n constructor(\n private bucketName: string,\n private http: HttpClient\n ) {}\n\n /**\n * Upload a file with a specific key\n * @param path - The object key/path\n * @param file - File or Blob to upload\n */\n async upload(\n path: string,\n file: File | Blob\n ): Promise<StorageResponse<StorageFileSchema>> {\n try {\n const formData = new FormData();\n formData.append('file', file);\n\n // Use PUT for specific path\n const response = await this.http.request<StorageFileSchema>(\n 'PUT',\n `/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`,\n {\n body: formData as any,\n headers: {\n // Don't set Content-Type, let browser set multipart boundary\n }\n }\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Upload failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Upload a file with auto-generated key\n * @param file - File or Blob to upload\n */\n async uploadAuto(\n file: File | Blob\n ): Promise<StorageResponse<StorageFileSchema>> {\n try {\n const formData = new FormData();\n formData.append('file', file);\n\n // Use POST for auto-generated key\n const response = await this.http.request<StorageFileSchema>(\n 'POST',\n `/api/storage/buckets/${this.bucketName}/objects`,\n {\n body: formData as any,\n headers: {\n // Don't set Content-Type, let browser set multipart boundary\n }\n }\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Upload failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Download a file\n * @param path - The object key/path\n * Returns the file as a Blob\n */\n async download(path: string): Promise<{ data: Blob | null; error: InsForgeError | null }> {\n try {\n // For binary data, we need to use fetch directly with proper response handling\n // The http.request method expects JSON responses, so we can't use it for blobs\n const url = `${this.http.baseUrl}/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`;\n \n const response = await this.http.fetch(url, {\n method: 'GET',\n headers: this.http.getHeaders()\n });\n\n if (!response.ok) {\n try {\n const error = await response.json();\n throw InsForgeError.fromApiError(error);\n } catch {\n throw new InsForgeError(\n `Download failed: ${response.statusText}`,\n response.status,\n 'STORAGE_ERROR'\n );\n }\n }\n\n const blob = await response.blob();\n return { data: blob, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Download failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Get public URL for a file\n * @param path - The object key/path\n */\n getPublicUrl(path: string): string {\n return `${this.http.baseUrl}/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`;\n }\n\n /**\n * List objects in the bucket\n * @param prefix - Filter by key prefix\n * @param search - Search in file names\n * @param limit - Maximum number of results (default: 100, max: 1000)\n * @param offset - Number of results to skip\n */\n async list(options?: {\n prefix?: string;\n search?: string;\n limit?: number;\n offset?: number;\n }): Promise<StorageResponse<ListObjectsResponseSchema>> {\n try {\n const params: Record<string, string> = {};\n \n if (options?.prefix) params.prefix = options.prefix;\n if (options?.search) params.search = options.search;\n if (options?.limit) params.limit = options.limit.toString();\n if (options?.offset) params.offset = options.offset.toString();\n\n const response = await this.http.get<ListObjectsResponseSchema>(\n `/api/storage/buckets/${this.bucketName}/objects`,\n { params }\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'List failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Delete a file\n * @param path - The object key/path\n */\n async remove(path: string): Promise<StorageResponse<{ message: string }>> {\n try {\n const response = await this.http.delete<{ message: string }>(\n `/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Delete failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n}\n\n/**\n * Storage module for file operations\n */\nexport class Storage {\n constructor(private http: HttpClient) {}\n\n /**\n * Get a bucket instance for operations\n * @param bucketName - Name of the bucket\n */\n from(bucketName: string): StorageBucket {\n return new StorageBucket(bucketName, this.http);\n }\n}","/**\n * AI Module for Insforge SDK\n * Wrapper for AI endpoints that follows OpenAI-like patterns\n * \n * The backend handles all the complexity of different AI providers\n * and returns a unified format. This SDK just calls the endpoints.\n */\n\nimport { HttpClient } from '../lib/http-client';\n\nexport class AI {\n public readonly chat: Chat;\n public readonly images: Images;\n\n constructor(private http: HttpClient) {\n this.chat = new Chat(http);\n this.images = new Images(http);\n }\n}\n\nclass Chat {\n public readonly completions: ChatCompletions;\n\n constructor(http: HttpClient) {\n this.completions = new ChatCompletions(http);\n }\n}\n\nclass ChatCompletions {\n constructor(private http: HttpClient) {}\n\n /**\n * Create a chat completion\n * \n * @example\n * ```typescript\n * // Non-streaming\n * const response = await client.ai.chat.completions.create({\n * model: 'gpt-4',\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n * console.log(response.response);\n * \n * // Streaming - returns async iterable\n * const stream = await client.ai.chat.completions.create({\n * model: 'gpt-4',\n * messages: [{ role: 'user', content: 'Tell me a story' }],\n * stream: true\n * });\n * \n * for await (const event of stream) {\n * if (event.chunk) {\n * process.stdout.write(event.chunk);\n * }\n * if (event.done) {\n * console.log('Stream complete!');\n * }\n * }\n * ```\n */\n async create(params: {\n model: string;\n messages?: Array<{ role: 'user' | 'assistant' | 'system'; content: string }>;\n message?: string;\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n systemPrompt?: string;\n stream?: boolean;\n }): Promise<any> {\n // For streaming, return an async iterable that yields parsed SSE events\n if (params.stream) {\n const headers = this.http.getHeaders();\n headers['Content-Type'] = 'application/json';\n \n const response = await this.http.fetch(\n `${this.http.baseUrl}/api/ai/chat`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(params)\n }\n );\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.error || 'Stream request failed');\n }\n\n // Return async iterable that parses SSE for the user\n return this.parseSSEStream(response);\n }\n\n // Non-streaming: use regular post method\n return this.http.post('/api/ai/chat', params);\n }\n\n /**\n * Parse SSE stream into async iterable of parsed events\n * Users don't need to handle SSE parsing themselves\n */\n private async *parseSSEStream(response: Response): AsyncIterableIterator<any> {\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const dataStr = line.slice(6).trim();\n if (dataStr) {\n try {\n const data = JSON.parse(dataStr);\n yield data;\n \n // If we received the done signal, we can stop\n if (data.done) {\n reader.releaseLock();\n return;\n }\n } catch (e) {\n // Skip invalid JSON\n console.warn('Failed to parse SSE data:', dataStr);\n }\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n\nclass Images {\n constructor(private http: HttpClient) {}\n\n /**\n * Generate images\n * \n * @example\n * ```typescript\n * const response = await client.ai.images.generate({\n * model: 'dall-e-3',\n * prompt: 'A sunset over mountains',\n * numImages: 1,\n * size: '1024x1024'\n * });\n * console.log(response.images[0].url);\n * ```\n */\n async generate(params: {\n model: string;\n prompt: string;\n negativePrompt?: string;\n width?: number;\n height?: number;\n numImages?: number;\n quality?: 'standard' | 'hd';\n style?: 'vivid' | 'natural';\n responseFormat?: 'url' | 'b64_json';\n size?: string;\n }) {\n // Backend expects these exact field names\n return this.http.post('/api/ai/image/generation', params);\n }\n}","import { InsForgeConfig } from './types';\nimport { HttpClient } from './lib/http-client';\nimport { TokenManager } from './lib/token-manager';\nimport { Auth } from './modules/auth';\nimport { Database } from './modules/database';\nimport { Storage } from './modules/storage';\nimport { AI } from './modules/ai';\n\n/**\n * Main InsForge SDK Client\n * \n * @example\n * ```typescript\n * import { InsForgeClient } from '@insforge/sdk';\n * \n * const client = new InsForgeClient({\n * baseUrl: 'http://localhost:7130'\n * });\n * \n * // Authentication\n * const session = await client.auth.register({\n * email: 'user@example.com',\n * password: 'password123',\n * name: 'John Doe'\n * });\n * \n * // Database operations\n * const { data, error } = await client.database\n * .from('posts')\n * .select('*')\n * .eq('user_id', session.user.id)\n * .order('created_at', { ascending: false })\n * .limit(10);\n * \n * // Insert data\n * const { data: newPost } = await client.database\n * .from('posts')\n * .insert({ title: 'Hello', content: 'World' })\n * .single();\n * ```\n */\nexport class InsForgeClient {\n private http: HttpClient;\n private tokenManager: TokenManager;\n \n public readonly auth: Auth;\n public readonly database: Database;\n public readonly storage: Storage;\n public readonly ai: AI;\n\n constructor(config: InsForgeConfig = {}) {\n this.http = new HttpClient(config);\n this.tokenManager = new TokenManager(config.storage);\n \n this.auth = new Auth(\n this.http,\n this.tokenManager\n );\n \n this.database = new Database(this.http);\n this.storage = new Storage(this.http);\n this.ai = new AI(this.http);\n }\n\n\n /**\n * Set a custom API key for authentication\n * This is useful for server-to-server communication\n * \n * @param apiKey - The API key (should start with 'ik_')\n * \n * @example\n * ```typescript\n * client.setApiKey('ik_your_api_key_here');\n * ```\n */\n setApiKey(apiKey: string): void {\n // API keys can be used as Bearer tokens\n this.http.setAuthToken(apiKey);\n }\n\n /**\n * Get the underlying HTTP client for custom requests\n * \n * @example\n * ```typescript\n * const httpClient = client.getHttpClient();\n * const customData = await httpClient.get('/api/custom-endpoint');\n * ```\n */\n getHttpClient(): HttpClient {\n return this.http;\n }\n\n /**\n * Future modules will be added here:\n * - database: Database operations\n * - storage: File storage operations\n * - functions: Serverless functions\n * - tables: Table management\n * - metadata: Backend metadata\n */\n}","/**\n * @insforge/sdk - TypeScript SDK for InsForge Backend-as-a-Service\n * \n * @packageDocumentation\n */\n\n// Main client\nexport { InsForgeClient } from './client';\n\n// Types\nexport type {\n InsForgeConfig,\n InsForgeConfig as ClientOptions, // Alias for compatibility\n TokenStorage,\n AuthSession,\n ApiError,\n} from './types';\n\nexport { InsForgeError } from './types';\n\n// Re-export shared schemas that SDK users will need\nexport type {\n UserSchema,\n CreateUserRequest,\n CreateSessionRequest,\n AuthErrorResponse,\n} from '@insforge/shared-schemas';\n\n// Re-export auth module for advanced usage\nexport { Auth } from './modules/auth';\n\n// Re-export database module and types\nexport { Database, QueryBuilder } from './modules/database';\nexport type { DatabaseResponse } from './modules/database';\n\n// Re-export storage module and types\nexport { Storage, StorageBucket } from './modules/storage';\nexport type { StorageResponse } from './modules/storage';\n\n// Re-export AI module\nexport { AI } from './modules/ai';\n\n// Re-export utilities for advanced usage\nexport { HttpClient } from './lib/http-client';\nexport { TokenManager } from './lib/token-manager';\n\n// Factory function for creating clients (Supabase-style)\nimport { InsForgeClient } from './client';\nimport { InsForgeConfig } from './types';\n\nexport function createClient(config: InsForgeConfig): InsForgeClient {\n return new InsForgeClient(config);\n}\n\n// Default export for convenience\nexport default InsForgeClient;"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/types.ts","../src/lib/http-client.ts","../src/lib/token-manager.ts","../src/modules/database.ts","../src/modules/auth.ts","../src/modules/storage.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["/**\n * InsForge SDK Types - only SDK-specific types here\n * Use @insforge/shared-schemas directly for API types\n */\n\nimport type { UserSchema } from '@insforge/shared-schemas';\n\nexport interface InsForgeConfig {\n /**\n * The base URL of the InsForge backend API\n * @default \"http://localhost:7130\"\n */\n baseUrl?: string;\n\n /**\n * API key (optional)\n * Can be used for server-side operations or specific use cases\n */\n apiKey?: string;\n\n /**\n * Custom fetch implementation (useful for Node.js environments)\n */\n fetch?: typeof fetch;\n\n /**\n * Storage adapter for persisting tokens\n */\n storage?: TokenStorage;\n\n /**\n * Whether to automatically refresh tokens before they expire\n * @default true\n */\n autoRefreshToken?: boolean;\n\n /**\n * Whether to persist session in storage\n * @default true\n */\n persistSession?: boolean;\n\n /**\n * Custom headers to include with every request\n */\n headers?: Record<string, string>;\n}\n\nexport interface TokenStorage {\n getItem(key: string): string | null | Promise<string | null>;\n setItem(key: string, value: string): void | Promise<void>;\n removeItem(key: string): void | Promise<void>;\n}\n\nexport interface AuthSession {\n user: UserSchema;\n accessToken: string;\n expiresAt?: Date;\n}\n\nexport interface ApiError {\n error: string;\n message: string;\n statusCode: number;\n nextActions?: string;\n}\n\nexport class InsForgeError extends Error {\n public statusCode: number;\n public error: string;\n public nextActions?: string;\n\n constructor(message: string, statusCode: number, error: string, nextActions?: string) {\n super(message);\n this.name = 'InsForgeError';\n this.statusCode = statusCode;\n this.error = error;\n this.nextActions = nextActions;\n }\n\n static fromApiError(apiError: ApiError): InsForgeError {\n return new InsForgeError(\n apiError.message,\n apiError.statusCode,\n apiError.error,\n apiError.nextActions\n );\n }\n}","import { InsForgeConfig, ApiError, InsForgeError } from '../types';\n\nexport interface RequestOptions extends RequestInit {\n params?: Record<string, string>;\n}\n\nexport class HttpClient {\n public readonly baseUrl: string;\n public readonly fetch: typeof fetch;\n private defaultHeaders: Record<string, string>;\n\n constructor(config: InsForgeConfig) {\n this.baseUrl = config.baseUrl || 'http://localhost:7130';\n // Properly bind fetch to maintain its context\n this.fetch = config.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined as any);\n this.defaultHeaders = {\n ...config.headers,\n };\n \n // Add API key if provided\n if (config.apiKey) {\n this.defaultHeaders['Authorization'] = `Bearer ${config.apiKey}`;\n }\n\n if (!this.fetch) {\n throw new Error(\n 'Fetch is not available. Please provide a fetch implementation in the config.'\n );\n }\n }\n\n private buildUrl(path: string, params?: Record<string, string>): string {\n const url = new URL(path, this.baseUrl);\n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n // For select parameter, preserve the exact formatting by normalizing whitespace\n // This ensures PostgREST relationship queries work correctly\n if (key === 'select') {\n // Normalize multiline select strings for PostgREST:\n // 1. Replace all whitespace (including newlines) with single space\n // 2. Remove spaces inside parentheses for proper PostgREST syntax\n // 3. Keep spaces after commas at the top level for readability\n let normalizedValue = value.replace(/\\s+/g, ' ').trim();\n \n // Fix spaces around parentheses and inside them\n normalizedValue = normalizedValue\n .replace(/\\s*\\(\\s*/g, '(') // Remove spaces around opening parens\n .replace(/\\s*\\)\\s*/g, ')') // Remove spaces around closing parens\n .replace(/\\(\\s+/g, '(') // Remove spaces after opening parens\n .replace(/\\s+\\)/g, ')') // Remove spaces before closing parens\n .replace(/,\\s+(?=[^()]*\\))/g, ','); // Remove spaces after commas inside parens\n \n url.searchParams.append(key, normalizedValue);\n } else {\n url.searchParams.append(key, value);\n }\n });\n }\n return url.toString();\n }\n\n async request<T>(\n method: string,\n path: string,\n options: RequestOptions = {}\n ): Promise<T> {\n const { params, headers = {}, body, ...fetchOptions } = options;\n \n const url = this.buildUrl(path, params);\n \n const requestHeaders: Record<string, string> = {\n ...this.defaultHeaders,\n };\n \n // Handle body serialization\n let processedBody: any;\n if (body !== undefined) {\n // Check if body is FormData (for file uploads)\n if (typeof FormData !== 'undefined' && body instanceof FormData) {\n // Don't set Content-Type for FormData, let browser set it with boundary\n processedBody = body;\n } else {\n // JSON body\n if (method !== 'GET') {\n requestHeaders['Content-Type'] = 'application/json;charset=UTF-8';\n }\n processedBody = JSON.stringify(body);\n }\n }\n \n Object.assign(requestHeaders, headers);\n \n const response = await this.fetch(url, {\n method,\n headers: requestHeaders,\n body: processedBody,\n ...fetchOptions,\n });\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n // Try to parse JSON response\n let data: any;\n const contentType = response.headers.get('content-type');\n // Check for any JSON content type (including PostgREST's vnd.pgrst.object+json)\n if (contentType?.includes('json')) {\n data = await response.json();\n } else {\n // For non-JSON responses, return text\n data = await response.text();\n }\n\n // Handle errors\n if (!response.ok) {\n if (data && typeof data === 'object' && 'error' in data) {\n throw InsForgeError.fromApiError(data as ApiError);\n }\n throw new InsForgeError(\n `Request failed: ${response.statusText}`,\n response.status,\n 'REQUEST_FAILED'\n );\n }\n\n return data as T;\n }\n\n get<T>(path: string, options?: RequestOptions): Promise<T> {\n return this.request<T>('GET', path, options);\n }\n\n post<T>(path: string, body?: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('POST', path, { ...options, body });\n }\n\n put<T>(path: string, body?: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('PUT', path, { ...options, body });\n }\n\n patch<T>(path: string, body?: any, options?: RequestOptions): Promise<T> {\n return this.request<T>('PATCH', path, { ...options, body });\n }\n\n delete<T>(path: string, options?: RequestOptions): Promise<T> {\n return this.request<T>('DELETE', path, options);\n }\n\n setAuthToken(token: string | null) {\n if (token) {\n this.defaultHeaders['Authorization'] = `Bearer ${token}`;\n } else {\n delete this.defaultHeaders['Authorization'];\n }\n }\n\n getHeaders(): Record<string, string> {\n return { ...this.defaultHeaders };\n }\n}","import { TokenStorage, AuthSession } from '../types';\n\nconst TOKEN_KEY = 'insforge-auth-token';\nconst USER_KEY = 'insforge-auth-user';\n\nexport class TokenManager {\n private storage: TokenStorage;\n\n constructor(storage?: TokenStorage) {\n if (storage) {\n // Use provided storage\n this.storage = storage;\n } else if (typeof window !== 'undefined' && window.localStorage) {\n // Browser: use localStorage\n this.storage = window.localStorage;\n } else {\n // Node.js: use in-memory storage\n const store = new Map<string, string>();\n this.storage = {\n getItem: (key: string) => store.get(key) || null,\n setItem: (key: string, value: string) => { store.set(key, value); },\n removeItem: (key: string) => { store.delete(key); }\n };\n }\n }\n\n saveSession(session: AuthSession): void {\n this.storage.setItem(TOKEN_KEY, session.accessToken);\n this.storage.setItem(USER_KEY, JSON.stringify(session.user));\n }\n\n getSession(): AuthSession | null {\n const token = this.storage.getItem(TOKEN_KEY);\n const userStr = this.storage.getItem(USER_KEY);\n\n if (!token || !userStr) {\n return null;\n }\n\n try {\n const user = JSON.parse(userStr as string);\n return { accessToken: token as string, user };\n } catch {\n this.clearSession();\n return null;\n }\n }\n\n getAccessToken(): string | null {\n const token = this.storage.getItem(TOKEN_KEY);\n return typeof token === 'string' ? token : null;\n }\n\n clearSession(): void {\n this.storage.removeItem(TOKEN_KEY);\n this.storage.removeItem(USER_KEY);\n }\n}","/**\n * Database module for InsForge SDK\n * Supabase-style query builder for PostgREST operations\n */\n\nimport { HttpClient } from '../lib/http-client';\nimport { InsForgeError } from '../types';\n\nexport interface DatabaseResponse<T> {\n data: T | null;\n error: InsForgeError | null;\n count?: number;\n}\n\n/**\n * Query builder for database operations\n * Uses method chaining like Supabase\n */\nexport class QueryBuilder<T = any> {\n private method: 'GET' | 'POST' | 'PATCH' | 'DELETE' = 'GET';\n private headers: Record<string, string> = {};\n private queryParams: Record<string, string> = {};\n private body?: any;\n\n constructor(\n private table: string,\n private http: HttpClient\n ) {}\n\n /**\n * Perform a SELECT query\n * For mutations (insert/update/delete), this enables returning data\n * @param columns - Columns to select (default: '*')\n * @example\n * .select('*')\n * .select('id, title, content')\n * .select('*, users!inner(*)') // Join with users table\n * .select('*, profile:profiles(*)') // Join with alias\n * .insert({ title: 'New' }).select() // Returns inserted data\n */\n select(columns: string = '*'): this {\n // For mutations, add return=representation header\n if (this.method !== 'GET') {\n const existingPrefer = this.headers['Prefer'] || '';\n const preferParts = existingPrefer ? [existingPrefer] : [];\n if (!preferParts.some(p => p.includes('return='))) {\n preferParts.push('return=representation');\n }\n this.headers['Prefer'] = preferParts.join(',');\n }\n \n // Always set the select parameter for GET requests\n // This enables PostgREST joins and nested queries\n if (this.method === 'GET' && columns) {\n this.queryParams.select = columns;\n } else if (columns !== '*') {\n // For mutations, only set if not default\n this.queryParams.select = columns;\n }\n return this;\n }\n\n /**\n * Perform an INSERT\n * @param values - Single object or array of objects\n * @param options - { upsert: true } for upsert behavior\n * @example\n * .insert({ title: 'Hello', content: 'World' }).select()\n * .insert([{ title: 'Post 1' }, { title: 'Post 2' }]).select()\n */\n insert(values: Partial<T> | Partial<T>[], options?: { upsert?: boolean }): this {\n this.method = 'POST';\n this.body = Array.isArray(values) ? values : [values];\n \n if (options?.upsert) {\n this.headers['Prefer'] = 'resolution=merge-duplicates';\n }\n \n return this;\n }\n\n /**\n * Perform an UPDATE\n * @param values - Object with fields to update\n * @example\n * .update({ title: 'Updated Title' }).select()\n */\n update(values: Partial<T>): this {\n this.method = 'PATCH';\n this.body = values;\n return this;\n }\n\n /**\n * Perform a DELETE\n * @example\n * .delete().select()\n */\n delete(): this {\n this.method = 'DELETE';\n return this;\n }\n\n /**\n * Perform an UPSERT\n * @param values - Single object or array of objects\n * @example\n * .upsert({ id: 1, title: 'Hello' })\n */\n upsert(values: Partial<T> | Partial<T>[]): this {\n return this.insert(values, { upsert: true });\n }\n\n // FILTERS\n\n /**\n * Filter by column equal to value\n * @example .eq('id', 123)\n */\n eq(column: string, value: any): this {\n this.queryParams[column] = `eq.${value}`;\n return this;\n }\n\n /**\n * Filter by column not equal to value\n * @example .neq('status', 'draft')\n */\n neq(column: string, value: any): this {\n this.queryParams[column] = `neq.${value}`;\n return this;\n }\n\n /**\n * Filter by column greater than value\n * @example .gt('age', 18)\n */\n gt(column: string, value: any): this {\n this.queryParams[column] = `gt.${value}`;\n return this;\n }\n\n /**\n * Filter by column greater than or equal to value\n * @example .gte('price', 100)\n */\n gte(column: string, value: any): this {\n this.queryParams[column] = `gte.${value}`;\n return this;\n }\n\n /**\n * Filter by column less than value\n * @example .lt('stock', 10)\n */\n lt(column: string, value: any): this {\n this.queryParams[column] = `lt.${value}`;\n return this;\n }\n\n /**\n * Filter by column less than or equal to value\n * @example .lte('discount', 50)\n */\n lte(column: string, value: any): this {\n this.queryParams[column] = `lte.${value}`;\n return this;\n }\n\n /**\n * Filter by pattern matching (case-sensitive)\n * @example .like('email', '%@gmail.com')\n */\n like(column: string, pattern: string): this {\n this.queryParams[column] = `like.${pattern}`;\n return this;\n }\n\n /**\n * Filter by pattern matching (case-insensitive)\n * @example .ilike('name', '%john%')\n */\n ilike(column: string, pattern: string): this {\n this.queryParams[column] = `ilike.${pattern}`;\n return this;\n }\n\n /**\n * Filter by checking if column is a value\n * @example .is('deleted_at', null)\n */\n is(column: string, value: null | boolean): this {\n if (value === null) {\n this.queryParams[column] = 'is.null';\n } else {\n this.queryParams[column] = `is.${value}`;\n }\n return this;\n }\n\n /**\n * Filter by checking if value is in array\n * @example .in('status', ['active', 'pending'])\n */\n in(column: string, values: any[]): this {\n this.queryParams[column] = `in.(${values.join(',')})`;\n return this;\n }\n\n // MODIFIERS\n\n /**\n * Order by column\n * @example \n * .order('created_at') // ascending\n * .order('created_at', { ascending: false }) // descending\n */\n order(column: string, options?: { ascending?: boolean }): this {\n const ascending = options?.ascending !== false;\n this.queryParams.order = ascending ? column : `${column}.desc`;\n return this;\n }\n\n /**\n * Limit the number of rows returned\n * @example .limit(10)\n */\n limit(count: number): this {\n this.queryParams.limit = count.toString();\n return this;\n }\n\n /**\n * Return results from an offset\n * @example .offset(20)\n */\n offset(count: number): this {\n this.queryParams.offset = count.toString();\n return this;\n }\n\n /**\n * Set a range of rows to return\n * @example .range(0, 9) // First 10 rows\n */\n range(from: number, to: number): this {\n this.headers['Range'] = `${from}-${to}`;\n return this;\n }\n\n /**\n * Return a single object instead of array\n * @example .single()\n */\n single(): this {\n this.headers['Accept'] = 'application/vnd.pgrst.object+json';\n return this;\n }\n\n /**\n * Get the total count (use with select)\n * @example .select('*', { count: 'exact' })\n */\n count(algorithm: 'exact' | 'planned' | 'estimated' = 'exact'): this {\n const prefer = this.headers['Prefer'] || '';\n this.headers['Prefer'] = prefer ? `${prefer},count=${algorithm}` : `count=${algorithm}`;\n return this;\n }\n\n /**\n * Execute the query and return results\n */\n async execute(): Promise<DatabaseResponse<T>> {\n try {\n const path = `/api/database/records/${this.table}`;\n let response: any;\n\n switch (this.method) {\n case 'GET':\n response = await this.http.get<T>(path, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n \n case 'POST':\n response = await this.http.post<T>(path, this.body, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n \n case 'PATCH':\n response = await this.http.patch<T>(path, this.body, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n \n case 'DELETE':\n response = await this.http.delete<T>(path, {\n params: this.queryParams,\n headers: this.headers\n });\n break;\n }\n\n return { data: response, error: null };\n } catch (error) {\n return {\n data: null,\n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Database operation failed',\n 500,\n 'DATABASE_ERROR'\n )\n };\n }\n }\n\n /**\n * Make QueryBuilder thenable for async/await\n */\n then<TResult1 = DatabaseResponse<T>, TResult2 = never>(\n onfulfilled?: ((value: DatabaseResponse<T>) => TResult1 | PromiseLike<TResult1>) | undefined | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null\n ): Promise<TResult1 | TResult2> {\n return this.execute().then(onfulfilled, onrejected);\n }\n}\n\n/**\n * Database client for InsForge SDK\n * Provides Supabase-style interface\n */\nexport class Database {\n constructor(private http: HttpClient) {}\n\n /**\n * Create a query builder for a table\n * @param table - The table name\n * @example\n * const { data, error } = await client.database\n * .from('posts')\n * .select('*')\n * .eq('user_id', userId)\n * .order('created_at', { ascending: false })\n * .limit(10);\n */\n from<T = any>(table: string): QueryBuilder<T> {\n return new QueryBuilder<T>(table, this.http);\n }\n}","/**\n * Auth module for InsForge SDK\n * Uses shared schemas for type safety\n */\n\nimport { HttpClient } from '../lib/http-client';\nimport { TokenManager } from '../lib/token-manager';\nimport { AuthSession, InsForgeError } from '../types';\nimport { Database } from './database';\n\nimport type {\n CreateUserRequest,\n CreateUserResponse,\n CreateSessionRequest,\n CreateSessionResponse,\n GetCurrentSessionResponse,\n GetOauthUrlResponse,\n} from '@insforge/shared-schemas';\n\nexport class Auth {\n private database: Database;\n \n constructor(\n private http: HttpClient,\n private tokenManager: TokenManager\n ) {\n this.database = new Database(http);\n \n // Auto-detect OAuth callback parameters in the URL\n this.detectOAuthCallback();\n }\n\n /**\n * Automatically detect and handle OAuth callback parameters in the URL\n * This runs on initialization to seamlessly complete the OAuth flow\n * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)\n */\n private detectOAuthCallback(): void {\n // Only run in browser environment\n if (typeof window === 'undefined') return;\n \n try {\n const params = new URLSearchParams(window.location.search);\n \n // Backend returns: access_token, user_id, email, name (optional)\n const accessToken = params.get('access_token');\n const userId = params.get('user_id');\n const email = params.get('email');\n const name = params.get('name');\n \n // Check if we have OAuth callback parameters\n if (accessToken && userId && email) {\n // Create session with the data from backend\n const session: AuthSession = {\n accessToken,\n user: {\n id: userId,\n email: email,\n name: name || '',\n // These fields are not provided by backend OAuth callback\n // They'll be populated when calling getCurrentUser()\n emailVerified: false,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n } as any,\n };\n \n // Save session and set auth token\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(accessToken);\n \n // Clean up the URL to remove sensitive parameters\n const url = new URL(window.location.href);\n url.searchParams.delete('access_token');\n url.searchParams.delete('user_id');\n url.searchParams.delete('email');\n url.searchParams.delete('name');\n \n // Also handle error case from backend (line 581)\n if (params.has('error')) {\n url.searchParams.delete('error');\n }\n \n // Replace URL without adding to browser history\n window.history.replaceState({}, document.title, url.toString());\n }\n } catch (error) {\n // Silently continue - don't break initialization\n console.debug('OAuth callback detection skipped:', error);\n }\n }\n\n /**\n * Sign up a new user\n */\n async signUp(request: CreateUserRequest): Promise<{\n data: CreateUserResponse | null;\n error: InsForgeError | null;\n }> {\n try {\n const response = await this.http.post<CreateUserResponse>('/api/auth/users', request);\n \n // Save session internally\n const session: AuthSession = {\n accessToken: response.accessToken,\n user: response.user,\n };\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(response.accessToken);\n\n return { \n data: response,\n error: null \n };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: null, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: null, \n error: new InsForgeError(\n error instanceof Error ? error.message : 'An unexpected error occurred during sign up',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Sign in with email and password\n */\n async signInWithPassword(request: CreateSessionRequest): Promise<{\n data: CreateSessionResponse | null;\n error: InsForgeError | null;\n }> {\n try {\n const response = await this.http.post<CreateSessionResponse>('/api/auth/sessions', request);\n \n // Save session internally\n const session: AuthSession = {\n accessToken: response.accessToken,\n user: response.user,\n };\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(response.accessToken);\n\n return { \n data: response,\n error: null \n };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: null, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: null, \n error: new InsForgeError(\n 'An unexpected error occurred during sign in',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Sign in with OAuth provider\n */\n async signInWithOAuth(options: {\n provider: 'google' | 'github';\n redirectTo?: string;\n skipBrowserRedirect?: boolean;\n }): Promise<{\n data: { url?: string; provider?: string };\n error: InsForgeError | null;\n }> {\n try {\n const { provider, redirectTo, skipBrowserRedirect } = options;\n \n const params = redirectTo \n ? { redirect_uri: redirectTo } \n : undefined;\n \n const endpoint = `/api/auth/oauth/${provider}`;\n const response = await this.http.get<GetOauthUrlResponse>(endpoint, { params });\n \n // Automatically redirect in browser unless told not to\n if (typeof window !== 'undefined' && !skipBrowserRedirect) {\n window.location.href = response.authUrl;\n return { data: {}, error: null };\n }\n\n return { \n data: { \n url: response.authUrl,\n provider \n }, \n error: null \n };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: {}, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: {}, \n error: new InsForgeError(\n 'An unexpected error occurred during OAuth initialization',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Sign out the current user\n */\n async signOut(): Promise<{ error: InsForgeError | null }> {\n try {\n this.tokenManager.clearSession();\n this.http.setAuthToken(null);\n return { error: null };\n } catch (error) {\n return { \n error: new InsForgeError(\n 'Failed to sign out',\n 500,\n 'SIGNOUT_ERROR'\n )\n };\n }\n }\n\n /**\n * Get the current user with full profile information\n * Returns both auth info (id, email, role) and profile data (nickname, avatar_url, bio, etc.)\n */\n async getCurrentUser(): Promise<{\n data: { user: any; profile: any } | null;\n error: InsForgeError | null;\n }> {\n try {\n // Check if we have a token\n const session = this.tokenManager.getSession();\n if (!session?.accessToken) {\n return { data: null, error: null };\n }\n\n // Call the API for auth info\n this.http.setAuthToken(session.accessToken);\n const authResponse = await this.http.get<GetCurrentSessionResponse>('/api/auth/sessions/current');\n \n // Get the user's profile using query builder\n const { data: profile, error: profileError } = await this.database\n .from('users')\n .select('*')\n .eq('id', authResponse.user.id)\n .single();\n \n if (profileError && profileError.statusCode !== 406) { // 406 = not found\n return { data: null, error: profileError };\n }\n \n return {\n data: {\n user: authResponse.user,\n profile: profile\n },\n error: null\n };\n } catch (error) {\n // If unauthorized, clear session\n if (error instanceof InsForgeError && error.statusCode === 401) {\n await this.signOut();\n return { data: null, error: null };\n }\n \n // Pass through all other errors unchanged\n if (error instanceof InsForgeError) {\n return { data: null, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: null, \n error: new InsForgeError(\n 'An unexpected error occurred while fetching user',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Get any user's profile by ID\n * Returns profile information from the users table (nickname, avatar_url, bio, etc.)\n */\n async getProfile(userId: string): Promise<{\n data: any | null;\n error: InsForgeError | null;\n }> {\n const { data, error } = await this.database\n .from('users')\n .select('*')\n .eq('id', userId)\n .single();\n \n // Handle not found as null, not error\n if (error && error.statusCode === 406) {\n return { data: null, error: null };\n }\n \n return { data, error };\n }\n\n /**\n * Get the current session (only session data, no API call)\n * Returns the stored JWT token and basic user info from local storage\n */\n async getCurrentSession(): Promise<{\n data: { session: AuthSession | null };\n error: InsForgeError | null;\n }> {\n try {\n const session = this.tokenManager.getSession();\n \n if (session?.accessToken) {\n this.http.setAuthToken(session.accessToken);\n return { data: { session }, error: null };\n }\n\n return { data: { session: null }, error: null };\n } catch (error) {\n // Pass through API errors unchanged\n if (error instanceof InsForgeError) {\n return { data: { session: null }, error };\n }\n \n // Generic fallback for unexpected errors\n return { \n data: { session: null }, \n error: new InsForgeError(\n 'An unexpected error occurred while getting session',\n 500,\n 'UNEXPECTED_ERROR'\n )\n };\n }\n }\n\n /**\n * Set/Update the current user's profile\n * Updates profile information in the users table (nickname, avatar_url, bio, etc.)\n */\n async setProfile(profile: {\n nickname?: string;\n avatar_url?: string;\n bio?: string;\n birthday?: string;\n [key: string]: any;\n }): Promise<{\n data: any | null;\n error: InsForgeError | null;\n }> {\n // Get current session to get user ID\n const session = this.tokenManager.getSession();\n if (!session?.user?.id) {\n return { \n data: null, \n error: new InsForgeError(\n 'No authenticated user found',\n 401,\n 'UNAUTHENTICATED'\n )\n };\n }\n\n // Update the profile using query builder\n return await this.database\n .from('users')\n .update(profile)\n .eq('id', session.user.id)\n .select()\n .single();\n }\n\n\n}","/**\n * Storage module for InsForge SDK\n * Handles file uploads, downloads, and bucket management\n */\n\nimport { HttpClient } from '../lib/http-client';\nimport { InsForgeError } from '../types';\nimport type { \n StorageFileSchema,\n ListObjectsResponseSchema\n} from '@insforge/shared-schemas';\n\nexport interface StorageResponse<T> {\n data: T | null;\n error: InsForgeError | null;\n}\n\n/**\n * Storage bucket operations\n */\nexport class StorageBucket {\n constructor(\n private bucketName: string,\n private http: HttpClient\n ) {}\n\n /**\n * Upload a file with a specific key\n * @param path - The object key/path\n * @param file - File or Blob to upload\n */\n async upload(\n path: string,\n file: File | Blob\n ): Promise<StorageResponse<StorageFileSchema>> {\n try {\n const formData = new FormData();\n formData.append('file', file);\n\n // Use PUT for specific path\n const response = await this.http.request<StorageFileSchema>(\n 'PUT',\n `/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`,\n {\n body: formData as any,\n headers: {\n // Don't set Content-Type, let browser set multipart boundary\n }\n }\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Upload failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Upload a file with auto-generated key\n * @param file - File or Blob to upload\n */\n async uploadAuto(\n file: File | Blob\n ): Promise<StorageResponse<StorageFileSchema>> {\n try {\n const formData = new FormData();\n formData.append('file', file);\n\n // Use POST for auto-generated key\n const response = await this.http.request<StorageFileSchema>(\n 'POST',\n `/api/storage/buckets/${this.bucketName}/objects`,\n {\n body: formData as any,\n headers: {\n // Don't set Content-Type, let browser set multipart boundary\n }\n }\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Upload failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Download a file\n * @param path - The object key/path\n * Returns the file as a Blob\n */\n async download(path: string): Promise<{ data: Blob | null; error: InsForgeError | null }> {\n try {\n // For binary data, we need to use fetch directly with proper response handling\n // The http.request method expects JSON responses, so we can't use it for blobs\n const url = `${this.http.baseUrl}/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`;\n \n const response = await this.http.fetch(url, {\n method: 'GET',\n headers: this.http.getHeaders()\n });\n\n if (!response.ok) {\n try {\n const error = await response.json();\n throw InsForgeError.fromApiError(error);\n } catch {\n throw new InsForgeError(\n `Download failed: ${response.statusText}`,\n response.status,\n 'STORAGE_ERROR'\n );\n }\n }\n\n const blob = await response.blob();\n return { data: blob, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Download failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Get public URL for a file\n * @param path - The object key/path\n */\n getPublicUrl(path: string): string {\n return `${this.http.baseUrl}/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`;\n }\n\n /**\n * List objects in the bucket\n * @param prefix - Filter by key prefix\n * @param search - Search in file names\n * @param limit - Maximum number of results (default: 100, max: 1000)\n * @param offset - Number of results to skip\n */\n async list(options?: {\n prefix?: string;\n search?: string;\n limit?: number;\n offset?: number;\n }): Promise<StorageResponse<ListObjectsResponseSchema>> {\n try {\n const params: Record<string, string> = {};\n \n if (options?.prefix) params.prefix = options.prefix;\n if (options?.search) params.search = options.search;\n if (options?.limit) params.limit = options.limit.toString();\n if (options?.offset) params.offset = options.offset.toString();\n\n const response = await this.http.get<ListObjectsResponseSchema>(\n `/api/storage/buckets/${this.bucketName}/objects`,\n { params }\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'List failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n\n /**\n * Delete a file\n * @param path - The object key/path\n */\n async remove(path: string): Promise<StorageResponse<{ message: string }>> {\n try {\n const response = await this.http.delete<{ message: string }>(\n `/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`\n );\n\n return { data: response, error: null };\n } catch (error) {\n return { \n data: null, \n error: error instanceof InsForgeError ? error : new InsForgeError(\n 'Delete failed',\n 500,\n 'STORAGE_ERROR'\n )\n };\n }\n }\n}\n\n/**\n * Storage module for file operations\n */\nexport class Storage {\n constructor(private http: HttpClient) {}\n\n /**\n * Get a bucket instance for operations\n * @param bucketName - Name of the bucket\n */\n from(bucketName: string): StorageBucket {\n return new StorageBucket(bucketName, this.http);\n }\n}","import { InsForgeConfig } from './types';\nimport { HttpClient } from './lib/http-client';\nimport { TokenManager } from './lib/token-manager';\nimport { Auth } from './modules/auth';\nimport { Database } from './modules/database';\nimport { Storage } from './modules/storage';\n\n/**\n * Main InsForge SDK Client\n * \n * @example\n * ```typescript\n * import { InsForgeClient } from '@insforge/sdk';\n * \n * const client = new InsForgeClient({\n * baseUrl: 'http://localhost:7130'\n * });\n * \n * // Authentication\n * const session = await client.auth.register({\n * email: 'user@example.com',\n * password: 'password123',\n * name: 'John Doe'\n * });\n * \n * // Database operations\n * const { data, error } = await client.database\n * .from('posts')\n * .select('*')\n * .eq('user_id', session.user.id)\n * .order('created_at', { ascending: false })\n * .limit(10);\n * \n * // Insert data\n * const { data: newPost } = await client.database\n * .from('posts')\n * .insert({ title: 'Hello', content: 'World' })\n * .single();\n * ```\n */\nexport class InsForgeClient {\n private http: HttpClient;\n private tokenManager: TokenManager;\n \n public readonly auth: Auth;\n public readonly database: Database;\n public readonly storage: Storage;\n\n constructor(config: InsForgeConfig = {}) {\n this.http = new HttpClient(config);\n this.tokenManager = new TokenManager(config.storage);\n \n this.auth = new Auth(\n this.http,\n this.tokenManager\n );\n \n this.database = new Database(this.http);\n this.storage = new Storage(this.http);\n }\n\n\n /**\n * Set a custom API key for authentication\n * This is useful for server-to-server communication\n * \n * @param apiKey - The API key (should start with 'ik_')\n * \n * @example\n * ```typescript\n * client.setApiKey('ik_your_api_key_here');\n * ```\n */\n setApiKey(apiKey: string): void {\n // API keys can be used as Bearer tokens\n this.http.setAuthToken(apiKey);\n }\n\n /**\n * Get the underlying HTTP client for custom requests\n * \n * @example\n * ```typescript\n * const httpClient = client.getHttpClient();\n * const customData = await httpClient.get('/api/custom-endpoint');\n * ```\n */\n getHttpClient(): HttpClient {\n return this.http;\n }\n\n /**\n * Future modules will be added here:\n * - database: Database operations\n * - storage: File storage operations\n * - functions: Serverless functions\n * - tables: Table management\n * - metadata: Backend metadata\n */\n}","/**\n * @insforge/sdk - TypeScript SDK for InsForge Backend-as-a-Service\n * \n * @packageDocumentation\n */\n\n// Main client\nexport { InsForgeClient } from './client';\n\n// Types\nexport type {\n InsForgeConfig,\n InsForgeConfig as ClientOptions, // Alias for compatibility\n TokenStorage,\n AuthSession,\n ApiError,\n} from './types';\n\nexport { InsForgeError } from './types';\n\n// Re-export shared schemas that SDK users will need\nexport type {\n UserSchema,\n CreateUserRequest,\n CreateSessionRequest,\n AuthErrorResponse,\n} from '@insforge/shared-schemas';\n\n// Re-export auth module for advanced usage\nexport { Auth } from './modules/auth';\n\n// Re-export database module and types\nexport { Database, QueryBuilder } from './modules/database';\nexport type { DatabaseResponse } from './modules/database';\n\n// Re-export storage module and types\nexport { Storage, StorageBucket } from './modules/storage';\nexport type { StorageResponse } from './modules/storage';\n\n// Re-export utilities for advanced usage\nexport { HttpClient } from './lib/http-client';\nexport { TokenManager } from './lib/token-manager';\n\n// Factory function for creating clients (Supabase-style)\nimport { InsForgeClient } from './client';\nimport { InsForgeConfig } from './types';\n\nexport function createClient(config: InsForgeConfig): InsForgeClient {\n return new InsForgeClient(config);\n}\n\n// Default export for convenience\nexport default InsForgeClient;"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@insforge/sdk",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
4
4
  "description": "TypeScript SDK for InsForge Backend-as-a-Service platform",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",