@mitway/sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,16 +2,16 @@
2
2
 
3
3
  TypeScript/JavaScript client for the **MITWAY-BaaS** backend. Lets end-user
4
4
  apps sign up, sign in, refresh tokens, and run PostgREST queries against a
5
- per-cliente MITWAY-BaaS deployment.
5
+ per-cliente MITWAY-BaaS deployment through a single public URL.
6
6
 
7
7
  ## Status
8
8
 
9
- **v0.1initial port.** Currently ships:
9
+ **v0.2.0backend proxy.** Currently ships:
10
10
 
11
11
  | Module | Status | Notes |
12
12
  |---|---|---|
13
13
  | `auth` | ✅ Working | `signUp`, `signInWithPassword`, `signOut`, `refreshSession`, `getSession`, `getUser` |
14
- | `database` | ✅ Working | PostgREST query builder via `@supabase/postgrest-js`, talks directly to the per-cliente PostgREST Service |
14
+ | `database` | ✅ Working | PostgREST query builder via `@supabase/postgrest-js`, routed through the backend proxy at `/api/database/records/*` and `/api/database/rpc/*` |
15
15
  | `storage` | ❌ Not yet | Backend has no `/api/storage/*` routes |
16
16
  | `functions` | ❌ Not yet | Backend has no `/api/functions/*` routes |
17
17
  | `email` | ❌ Not yet | Backend has no `/api/email/*` routes |
@@ -37,9 +37,8 @@ pnpm add @mitway/sdk
37
37
  import { createClient } from '@mitway/sdk';
38
38
 
39
39
  const client = createClient({
40
- baseUrl: 'https://acme.api.dev.nttmitway.com', // backend (auth)
41
- postgrestUrl: 'https://acme.db.dev.nttmitway.com', // postgrest (db)
42
- anonKey: 'eyJhbGciOiJIUzI1NiIs...', // optional; signed JWT with role=anon
40
+ baseUrl: 'https://acme.api.dev.nttmitway.com', // single backend URL
41
+ anonKey: 'eyJhbGciOiJIUzI1NiIs...', // optional; signed JWT with role=anon
43
42
  });
44
43
 
45
44
  // Sign up
@@ -83,7 +82,6 @@ await client.auth.signOut();
83
82
  ```typescript
84
83
  interface MitwayBaasConfig {
85
84
  baseUrl?: string; // default 'http://localhost:7130'
86
- postgrestUrl?: string; // optional; required to use client.database
87
85
  anonKey?: string; // optional fallback bearer for unauthenticated requests
88
86
  fetch?: typeof fetch; // override (Node < 18, tests, etc.)
89
87
  headers?: Record<string, string>;
@@ -95,10 +93,10 @@ interface MitwayBaasConfig {
95
93
  }
96
94
  ```
97
95
 
98
- `baseUrl` and `postgrestUrl` are intentionally separate because the per-cliente
99
- deployment runs the backend (`mitway-baas-{client}` Service, port 7130) and
100
- PostgREST (`mitway-baas-{client}-postgrest` Service, port 3000) as independent
101
- Pods in the same namespace. Each needs its own public ingress in production.
96
+ `baseUrl` is the **only** URL consumers need. Auth, database, and (in the
97
+ future) storage/functions all route through the same backend. PostgREST
98
+ is an internal ClusterIP Pod per cliente and is never publicly exposed —
99
+ the backend proxies database requests to it over the cluster network.
102
100
 
103
101
  ## Auth flow
104
102
 
@@ -122,11 +120,22 @@ don't need to manage refresh manually.
122
120
 
123
121
  The `database` module is a thin wrapper around
124
122
  [`@supabase/postgrest-js`](https://github.com/supabase/postgrest-js)
125
- configured to talk directly to the per-cliente PostgREST. The full
123
+ configured with a custom fetch that rewrites every outgoing URL:
124
+
125
+ - `http://dummy/{table}?…` → `{baseUrl}/api/database/records/{table}?…`
126
+ - `http://dummy/rpc/{fn}?…` → `{baseUrl}/api/database/rpc/{fn}?…`
127
+
128
+ These paths hit the MITWAY-BaaS backend, which then proxies the request
129
+ internally to the per-cliente PostgREST Pod (`mitway-baas-{client}-postgrest:3000`)
130
+ over the cluster network. PostgREST verifies the JWT with the shared
131
+ tenant `JWT_SECRET` and enforces RLS based on the role claim.
132
+
133
+ The full
126
134
  [PostgREST query builder API](https://supabase.com/docs/reference/javascript/select)
127
135
  is available: `select`, `insert`, `update`, `upsert`, `delete`, `rpc`,
128
136
  filters (`.eq`, `.neq`, `.gt`, `.like`, `.in`, …), modifiers (`.order`,
129
- `.limit`, `.range`, `.single`, …), foreign-key joins (`select('*, author:users(*)')`).
137
+ `.limit`, `.range`, `.single`, …), foreign-key joins
138
+ (`select('*, author:users(*)')`).
130
139
 
131
140
  Authorization is read from the `TokenManager` on every request, so a
132
141
  sign-in/sign-out is picked up automatically — no need to recreate the client.
@@ -134,9 +143,9 @@ sign-in/sign-out is picked up automatically — no need to recreate the client.
134
143
  ## Origin
135
144
 
136
145
  Forked structurally from
137
- [`InsForge/InsForge-sdk-js`](https://github.com/InsForge/InsForge-sdk-js)
138
- (commit at the time of the port). Kept the `lib/` infrastructure
139
- (http-client, token-manager, logger) almost verbatim with rebranding.
140
- Rewrote `auth` for the MITWAY-BaaS routes and `database` to talk to
141
- PostgREST directly instead of going through a backend proxy that
142
- MITWAY-BaaS does not have.
146
+ [`InsForge/InsForge-sdk-js`](https://github.com/InsForge/InsForge-sdk-js).
147
+ Kept the `lib/` infrastructure (http-client, token-manager, logger)
148
+ almost verbatim with rebranding. Rewrote `auth` for the MITWAY-BaaS
149
+ routes and `database` to use the same fetch-rewriting pattern as
150
+ upstream both hit a backend proxy that forwards to the internal
151
+ PostgREST, collapsing the per-cliente public surface into a single URL.
package/dist/index.cjs CHANGED
@@ -736,8 +736,14 @@ var Auth = class {
736
736
 
737
737
  // src/modules/database.ts
738
738
  var import_postgrest_js = require("@supabase/postgrest-js");
739
- function createAuthedFetch(tokenManager, anonKey) {
739
+ function createMitwayBaasFetch(httpClient, tokenManager, anonKey) {
740
740
  return async (input, init) => {
741
+ const url = typeof input === "string" ? input : input.toString();
742
+ const urlObj = new URL(url);
743
+ const pathname = urlObj.pathname.startsWith("/") ? urlObj.pathname.slice(1) : urlObj.pathname;
744
+ const rpcMatch = pathname.match(/^rpc\/(.+)$/);
745
+ const endpoint = rpcMatch ? `/api/database/rpc/${rpcMatch[1]}` : `/api/database/records/${pathname}`;
746
+ const targetUrl = `${httpClient.baseUrl}${endpoint}${urlObj.search}`;
741
747
  const headers = new Headers(init?.headers);
742
748
  if (!headers.has("Authorization")) {
743
749
  const token = tokenManager.getAccessToken() ?? anonKey;
@@ -745,32 +751,18 @@ function createAuthedFetch(tokenManager, anonKey) {
745
751
  headers.set("Authorization", `Bearer ${token}`);
746
752
  }
747
753
  }
748
- return fetch(input, { ...init, headers });
754
+ return fetch(targetUrl, { ...init, headers });
749
755
  };
750
756
  }
751
757
  var Database = class {
752
758
  postgrest;
753
- postgrestUrl;
754
- constructor(tokenManager, postgrestUrl, anonKey) {
755
- this.postgrestUrl = postgrestUrl;
756
- if (postgrestUrl) {
757
- this.postgrest = new import_postgrest_js.PostgrestClient(postgrestUrl, {
758
- fetch: createAuthedFetch(tokenManager, anonKey),
759
- headers: {}
760
- });
761
- } else {
762
- this.postgrest = null;
763
- }
764
- }
765
- requireClient() {
766
- if (!this.postgrest) {
767
- throw new MitwayBaasError(
768
- "Database is not configured. Pass `postgrestUrl` in the SDK config to enable database operations.",
769
- 500,
770
- "DATABASE_NOT_CONFIGURED"
771
- );
772
- }
773
- return this.postgrest;
759
+ httpClient;
760
+ constructor(httpClient, tokenManager, anonKey) {
761
+ this.httpClient = httpClient;
762
+ this.postgrest = new import_postgrest_js.PostgrestClient("http://dummy", {
763
+ fetch: createMitwayBaasFetch(httpClient, tokenManager, anonKey),
764
+ headers: {}
765
+ });
774
766
  }
775
767
  /**
776
768
  * Build a PostgREST query against a table.
@@ -791,7 +783,14 @@ var Database = class {
791
783
  * .single();
792
784
  */
793
785
  from(table) {
794
- return this.requireClient().from(table);
786
+ if (!table || typeof table !== "string") {
787
+ throw new MitwayBaasError(
788
+ "Database.from(table) requires a non-empty string",
789
+ 400,
790
+ "INVALID_TABLE_NAME"
791
+ );
792
+ }
793
+ return this.postgrest.from(table);
795
794
  }
796
795
  /**
797
796
  * Call a PostgreSQL stored function (RPC).
@@ -801,14 +800,15 @@ var Database = class {
801
800
  * .rpc('get_user_stats', { user_id: 123 });
802
801
  */
803
802
  rpc(fn, args, options) {
804
- return this.requireClient().rpc(fn, args, options);
803
+ return this.postgrest.rpc(fn, args, options);
805
804
  }
806
805
  /**
807
- * The PostgREST URL the database client is talking to, or undefined if
808
- * the database module is not configured.
806
+ * The backend base URL the database client is targeting. Useful for
807
+ * debugging — the actual PostgREST instance is internal and not
808
+ * reachable by the SDK directly.
809
809
  */
810
810
  getUrl() {
811
- return this.postgrestUrl;
811
+ return this.httpClient.baseUrl;
812
812
  }
813
813
  };
814
814
 
@@ -823,7 +823,7 @@ var MitwayBaasClient = class {
823
823
  this.tokenManager = new TokenManager();
824
824
  this.http = new HttpClient(config, this.tokenManager, logger);
825
825
  this.auth = new Auth(this.http, this.tokenManager);
826
- this.database = new Database(this.tokenManager, config.postgrestUrl, config.anonKey);
826
+ this.database = new Database(this.http, this.tokenManager, config.anonKey);
827
827
  }
828
828
  /**
829
829
  * Escape hatch for callers that need to make custom requests against the
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/lib/logger.ts","../src/lib/token-manager.ts","../src/lib/http-client.ts","../src/modules/auth.ts","../src/modules/database.ts","../src/client.ts"],"sourcesContent":["/**\n * @mitway-baas/sdk — TypeScript SDK for the MITWAY-BaaS backend.\n *\n * Currently ships:\n * - auth (signUp, signInWithPassword, signOut, refreshSession, getSession, getUser)\n * - database (PostgREST-backed query builder via @supabase/postgrest-js)\n *\n * Not yet included (no backend support):\n * - storage\n * - functions\n * - email\n * - ai\n * - realtime\n *\n * @packageDocumentation\n */\n\nexport { MitwayBaasClient } from './client';\n\nimport { MitwayBaasClient } from './client';\nimport { MitwayBaasConfig } from './types';\n\n/**\n * Factory function for creating SDK clients (Supabase-style).\n *\n * @example\n * ```typescript\n * import { createClient } from '@mitway-baas/sdk';\n *\n * const client = createClient({\n * baseUrl: 'https://acme.api.dev.nttmitway.com',\n * postgrestUrl: 'https://acme.db.dev.nttmitway.com',\n * });\n * ```\n */\nexport function createClient(config: MitwayBaasConfig): MitwayBaasClient {\n return new MitwayBaasClient(config);\n}\n\n// Default export for `import client from '@mitway-baas/sdk'`\nexport default MitwayBaasClient;\n\n// Public types\nexport type {\n MitwayBaasConfig,\n AuthSession,\n AuthRefreshResponse,\n ApiError,\n} from './types';\nexport { MitwayBaasError } from './types';\n\n// Re-export module classes for advanced/TypeScript-friendly usage\nexport { Auth } from './modules/auth';\nexport type { SignUpRequest, SignInRequest, AuthResponse, AuthResult } from './modules/auth';\nexport { Database } from './modules/database';\n\n// Re-export low-level helpers (most consumers won't need these)\nexport { HttpClient } from './lib/http-client';\nexport { TokenManager } from './lib/token-manager';\nexport { Logger } from './lib/logger';\n\n// Public User shape — inlined in lib/user so this package has no\n// MITWAY-BaaS workspace dependencies.\nexport type { User } from './lib/user';\n","/**\n * MITWAY-BaaS SDK types — only SDK-specific shapes live here.\n * The `User` shape is inlined in `./lib/user` so this package has zero\n * MITWAY-BaaS workspace dependencies.\n */\n\nimport type { User } from './lib/user';\n\nexport interface MitwayBaasConfig {\n /**\n * Base URL of the MITWAY-BaaS backend (auth, metadata, etc).\n * @default \"http://localhost:7130\"\n */\n baseUrl?: string;\n\n /**\n * Base URL of the per-cliente PostgREST instance. Used by the database\n * module. If omitted, calling `client.database.from(...)` will throw at\n * call time. The PostgREST URL is separate from `baseUrl` because the two\n * services are deployed as independent Pods in the per-cliente namespace.\n */\n postgrestUrl?: string;\n\n /**\n * Anonymous JWT (signed by the tenant's JWT_SECRET, role = \"anon\").\n * Used as a fallback Bearer token for unauthenticated requests when no\n * user session is active.\n */\n anonKey?: string;\n\n /**\n * Custom fetch implementation. Useful in Node < 18 or test environments.\n * Defaults to `globalThis.fetch`.\n */\n fetch?: typeof fetch;\n\n /**\n * Custom default headers included on every request.\n */\n headers?: Record<string, string>;\n\n /**\n * Enable debug logging. `true` logs to console; pass a function to receive\n * log lines instead.\n */\n debug?: boolean | ((message: string, ...args: any[]) => void);\n\n /**\n * Per-request timeout in milliseconds. 0 disables the timeout.\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Number of retry attempts on network errors and 5xx responses. Client\n * errors (4xx) are never retried. 0 disables retries.\n * @default 3\n */\n retryCount?: number;\n\n /**\n * Initial delay before the first retry, in ms. Doubles each attempt with\n * ±15% jitter.\n * @default 500\n */\n retryDelay?: number;\n\n /**\n * Automatically refresh the access token on 401 INVALID_TOKEN responses\n * and retry the original request.\n * @default true\n */\n autoRefreshToken?: boolean;\n}\n\n/**\n * Active user session in memory. Mirrors what the auth endpoints return.\n */\nexport interface AuthSession {\n user: User;\n accessToken: string;\n expiresAt?: Date;\n}\n\n/**\n * Minimal payload that auth refresh endpoints emit. The SDK uses this to\n * refresh the in-memory session.\n */\nexport interface AuthRefreshResponse {\n user: User;\n accessToken: string;\n refreshToken?: string;\n csrfToken?: string;\n}\n\n/**\n * The `{ data, error }` envelope used by the MITWAY-BaaS backend on every\n * response. The SDK unwraps `data` for happy-path returns and converts\n * `error` into a `MitwayBaasError`.\n */\nexport interface ApiError {\n error: string;\n message: string;\n statusCode: number;\n nextActions?: string;\n}\n\nexport class MitwayBaasError extends Error {\n public statusCode: number;\n public error: string;\n public nextActions?: string;\n\n constructor(\n message: string,\n statusCode: number,\n error: string,\n nextActions?: string,\n ) {\n super(message);\n this.name = 'MitwayBaasError';\n this.statusCode = statusCode;\n this.error = error;\n this.nextActions = nextActions;\n }\n\n static fromApiError(apiError: ApiError): MitwayBaasError {\n return new MitwayBaasError(\n apiError.message,\n apiError.statusCode,\n apiError.error,\n apiError.nextActions,\n );\n }\n}\n","/**\n * Debug logger for the MITWAY-BaaS SDK.\n *\n * Logs HTTP request/response details with automatic redaction of sensitive\n * headers and body fields. Disabled by default; pass `debug: true` (or a\n * custom log function) on the SDK config to enable.\n */\n\ntype LogFunction = (message: string, ...args: any[]) => void;\n\nconst SENSITIVE_HEADERS = ['authorization', 'x-api-key', 'cookie', 'set-cookie'];\n\nconst SENSITIVE_BODY_KEYS = [\n 'password', 'token', 'accesstoken', 'refreshtoken',\n 'authorization', 'secret', 'apikey', 'api_key',\n 'email', 'ssn', 'creditcard', 'credit_card',\n];\n\nfunction redactHeaders(headers: Record<string, string>): Record<string, string> {\n const redacted: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (SENSITIVE_HEADERS.includes(key.toLowerCase())) {\n redacted[key] = '***REDACTED***';\n } else {\n redacted[key] = value;\n }\n }\n return redacted;\n}\n\nfunction sanitizeBody(body: any): any {\n if (body === null || body === undefined) return body;\n if (typeof body === 'string') {\n try {\n const parsed = JSON.parse(body);\n return sanitizeBody(parsed);\n } catch {\n return body;\n }\n }\n if (Array.isArray(body)) return body.map(sanitizeBody);\n if (typeof body === 'object') {\n const sanitized: Record<string, any> = {};\n for (const [key, value] of Object.entries(body)) {\n if (SENSITIVE_BODY_KEYS.includes(key.toLowerCase().replace(/[-_]/g, ''))) {\n sanitized[key] = '***REDACTED***';\n } else {\n sanitized[key] = sanitizeBody(value);\n }\n }\n return sanitized;\n }\n return body;\n}\n\nfunction formatBody(body: any): string {\n if (body === undefined || body === null) return '';\n if (typeof body === 'string') {\n try {\n return JSON.stringify(JSON.parse(body), null, 2);\n } catch {\n return body;\n }\n }\n if (typeof FormData !== 'undefined' && body instanceof FormData) {\n return '[FormData]';\n }\n try {\n return JSON.stringify(body, null, 2);\n } catch {\n return '[Unserializable body]';\n }\n}\n\nexport class Logger {\n public enabled: boolean;\n private customLog: LogFunction | null;\n\n constructor(debug?: boolean | LogFunction) {\n if (typeof debug === 'function') {\n this.enabled = true;\n this.customLog = debug;\n } else {\n this.enabled = !!debug;\n this.customLog = null;\n }\n }\n\n log(message: string, ...args: any[]): void {\n if (!this.enabled) return;\n const formatted = `[MITWAY-BaaS Debug] ${message}`;\n if (this.customLog) {\n this.customLog(formatted, ...args);\n } else {\n console.log(formatted, ...args);\n }\n }\n\n warn(message: string, ...args: any[]): void {\n if (!this.enabled) return;\n const formatted = `[MITWAY-BaaS Debug] ${message}`;\n if (this.customLog) {\n this.customLog(formatted, ...args);\n } else {\n console.warn(formatted, ...args);\n }\n }\n\n error(message: string, ...args: any[]): void {\n if (!this.enabled) return;\n const formatted = `[MITWAY-BaaS Debug] ${message}`;\n if (this.customLog) {\n this.customLog(formatted, ...args);\n } else {\n console.error(formatted, ...args);\n }\n }\n\n logRequest(\n method: string,\n url: string,\n headers?: Record<string, string>,\n body?: any\n ): void {\n if (!this.enabled) return;\n const parts: string[] = [`→ ${method} ${url}`];\n if (headers && Object.keys(headers).length > 0) {\n parts.push(` Headers: ${JSON.stringify(redactHeaders(headers))}`);\n }\n const formattedBody = formatBody(sanitizeBody(body));\n if (formattedBody) {\n const truncated = formattedBody.length > 1000\n ? formattedBody.slice(0, 1000) + '... [truncated]'\n : formattedBody;\n parts.push(` Body: ${truncated}`);\n }\n this.log(parts.join('\\n'));\n }\n\n logResponse(\n method: string,\n url: string,\n status: number,\n durationMs: number,\n body?: any\n ): void {\n if (!this.enabled) return;\n const parts: string[] = [\n `← ${method} ${url} ${status} (${durationMs}ms)`,\n ];\n const formattedBody = formatBody(sanitizeBody(body));\n if (formattedBody) {\n const truncated = formattedBody.length > 1000\n ? formattedBody.slice(0, 1000) + '... [truncated]'\n : formattedBody;\n parts.push(` Body: ${truncated}`);\n }\n if (status >= 400) {\n this.error(parts.join('\\n'));\n } else {\n this.log(parts.join('\\n'));\n }\n }\n}\n","/**\n * Token Manager for the MITWAY-BaaS SDK.\n *\n * In-memory storage for the access token + user. Browser CSRF token lives\n * in a cookie so the cookie-based refresh flow works across page reloads.\n */\n\nimport type { User } from './user';\nimport type { AuthSession } from '../types';\n\nexport const CSRF_TOKEN_COOKIE = 'mitway_baas_csrf_token';\n\nexport function getCsrfToken(): string | null {\n if (typeof document === 'undefined') return null;\n const match = document.cookie\n .split(';')\n .find((c) => c.trim().startsWith(`${CSRF_TOKEN_COOKIE}=`));\n if (!match) return null;\n return match.split('=')[1] || null;\n}\n\nexport function setCsrfToken(token: string): void {\n if (typeof document === 'undefined') return;\n const maxAge = 7 * 24 * 60 * 60; // 7 days\n const secure =\n typeof window !== 'undefined' && window.location.protocol === 'https:'\n ? '; Secure'\n : '';\n document.cookie = `${CSRF_TOKEN_COOKIE}=${encodeURIComponent(token)}; path=/; max-age=${maxAge}; SameSite=Lax${secure}`;\n}\n\nexport function clearCsrfToken(): void {\n if (typeof document === 'undefined') return;\n const secure =\n typeof window !== 'undefined' && window.location.protocol === 'https:'\n ? '; Secure'\n : '';\n document.cookie = `${CSRF_TOKEN_COOKIE}=; path=/; max-age=0; SameSite=Lax${secure}`;\n}\n\nexport class TokenManager {\n private accessToken: string | null = null;\n private user: User | null = null;\n\n /** Fired when the access token changes (used by long-lived consumers). */\n onTokenChange: (() => void) | null = null;\n\n saveSession(session: AuthSession): void {\n const tokenChanged = session.accessToken !== this.accessToken;\n this.accessToken = session.accessToken;\n this.user = session.user;\n if (tokenChanged && this.onTokenChange) {\n this.onTokenChange();\n }\n }\n\n getSession(): AuthSession | null {\n if (!this.accessToken || !this.user) return null;\n return {\n accessToken: this.accessToken,\n user: this.user,\n };\n }\n\n getAccessToken(): string | null {\n return this.accessToken;\n }\n\n setAccessToken(token: string): void {\n const tokenChanged = token !== this.accessToken;\n this.accessToken = token;\n if (tokenChanged && this.onTokenChange) {\n this.onTokenChange();\n }\n }\n\n getUser(): User | null {\n return this.user;\n }\n\n setUser(user: User): void {\n this.user = user;\n }\n\n clearSession(): void {\n const hadToken = this.accessToken !== null;\n this.accessToken = null;\n this.user = null;\n if (hadToken && this.onTokenChange) {\n this.onTokenChange();\n }\n }\n}\n","/**\n * HttpClient with retry, timeout, abort signal composition, and automatic\n * token refresh on 401 INVALID_TOKEN responses.\n *\n * Ported from the InsForge SDK with rebranding plus one route change:\n * the refresh endpoint is `/api/auth/refresh` (MITWAY-BaaS) instead of\n * `/api/auth/sessions/current` (InsForge).\n */\n\nimport {\n MitwayBaasConfig,\n ApiError,\n MitwayBaasError,\n AuthRefreshResponse,\n} from '../types';\nimport { Logger } from './logger';\nimport {\n clearCsrfToken,\n getCsrfToken,\n setCsrfToken,\n TokenManager,\n} from './token-manager';\n\ntype JsonRequestBody = Record<string, unknown> | unknown[] | null;\n\nexport interface RequestOptions extends Omit<RequestInit, 'body'> {\n params?: Record<string, string>;\n body?: RequestInit['body'] | JsonRequestBody;\n /**\n * Allow retrying non-idempotent requests (POST, PATCH). Off by default to\n * prevent duplicate writes on transient server errors.\n */\n idempotent?: boolean;\n}\n\nconst RETRYABLE_STATUS_CODES = new Set([500, 502, 503, 504]);\nconst IDEMPOTENT_METHODS = new Set(['GET', 'HEAD', 'PUT', 'DELETE', 'OPTIONS']);\n\nexport class HttpClient {\n public readonly baseUrl: string;\n public readonly fetch: typeof fetch;\n private defaultHeaders: Record<string, string>;\n private anonKey: string | undefined;\n private userToken: string | null = null;\n private logger: Logger;\n private autoRefreshToken: boolean = true;\n private isRefreshing: boolean = false;\n private refreshPromise: Promise<AuthRefreshResponse> | null = null;\n private tokenManager: TokenManager;\n private refreshToken: string | null = null;\n private timeout: number;\n private retryCount: number;\n private retryDelay: number;\n\n constructor(\n config: MitwayBaasConfig,\n tokenManager?: TokenManager,\n logger?: Logger,\n ) {\n this.baseUrl = config.baseUrl || 'http://localhost:7130';\n this.autoRefreshToken = config.autoRefreshToken ?? true;\n this.fetch =\n config.fetch ||\n (globalThis.fetch\n ? globalThis.fetch.bind(globalThis)\n : (undefined as any));\n this.anonKey = config.anonKey;\n this.defaultHeaders = {\n ...config.headers,\n };\n this.tokenManager = tokenManager ?? new TokenManager();\n this.logger = logger || new Logger(false);\n this.timeout = config.timeout ?? 30_000;\n this.retryCount = config.retryCount ?? 3;\n this.retryDelay = config.retryDelay ?? 500;\n\n if (!this.fetch) {\n throw new Error(\n 'Fetch is not available. Provide a fetch implementation in the SDK 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 if (key === 'select') {\n // Normalize PostgREST select syntax (whitespace inside relationships).\n let normalizedValue = value.replace(/\\s+/g, ' ').trim();\n normalizedValue = normalizedValue\n .replace(/\\s*\\(\\s*/g, '(')\n .replace(/\\s*\\)\\s*/g, ')')\n .replace(/\\(\\s+/g, '(')\n .replace(/\\s+\\)/g, ')')\n .replace(/,\\s+(?=[^()]*\\))/g, ',');\n url.searchParams.append(key, normalizedValue);\n } else {\n url.searchParams.append(key, value);\n }\n });\n }\n return url.toString();\n }\n\n private isRetryableStatus(status: number): boolean {\n return RETRYABLE_STATUS_CODES.has(status);\n }\n\n private computeRetryDelay(attempt: number): number {\n const base = this.retryDelay * Math.pow(2, attempt - 1);\n const jitter = base * (0.85 + Math.random() * 0.3);\n return Math.round(jitter);\n }\n\n private async handleRequest<T>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n const {\n params,\n headers = {},\n body,\n signal: callerSignal,\n ...fetchOptions\n } = options as RequestOptions & { signal?: AbortSignal };\n\n const url = this.buildUrl(path, params);\n const startTime = Date.now();\n const canRetry =\n IDEMPOTENT_METHODS.has(method.toUpperCase()) ||\n options.idempotent === true;\n const maxAttempts = canRetry ? this.retryCount : 0;\n\n const requestHeaders: Record<string, string> = {\n ...this.defaultHeaders,\n };\n\n const authToken = this.userToken || this.anonKey;\n if (authToken) {\n requestHeaders['Authorization'] = `Bearer ${authToken}`;\n }\n\n let processedBody: any;\n if (body !== undefined) {\n if (typeof FormData !== 'undefined' && body instanceof FormData) {\n processedBody = body;\n } else {\n if (method !== 'GET') {\n requestHeaders['Content-Type'] = 'application/json;charset=UTF-8';\n }\n processedBody = JSON.stringify(body);\n }\n }\n\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n requestHeaders[key] = value;\n });\n } else if (Array.isArray(headers)) {\n headers.forEach(([key, value]) => {\n requestHeaders[key] = value;\n });\n } else {\n Object.assign(requestHeaders, headers);\n }\n\n this.logger.logRequest(method, url, requestHeaders, processedBody);\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxAttempts; attempt++) {\n if (attempt > 0) {\n const delay = this.computeRetryDelay(attempt);\n this.logger.warn(\n `Retry ${attempt}/${maxAttempts} for ${method} ${url} in ${delay}ms`,\n );\n if (callerSignal?.aborted) throw callerSignal.reason;\n await new Promise<void>((resolve, reject) => {\n const onAbort = () => {\n clearTimeout(timer);\n reject(callerSignal!.reason);\n };\n const timer = setTimeout(() => {\n if (callerSignal)\n callerSignal.removeEventListener('abort', onAbort);\n resolve();\n }, delay);\n if (callerSignal) {\n callerSignal.addEventListener('abort', onAbort, { once: true });\n }\n });\n }\n\n let controller: AbortController | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n if (this.timeout > 0 || callerSignal) {\n controller = new AbortController();\n\n if (this.timeout > 0) {\n timer = setTimeout(() => controller!.abort(), this.timeout);\n }\n\n if (callerSignal) {\n if (callerSignal.aborted) {\n controller.abort(callerSignal.reason);\n } else {\n const onCallerAbort = () => controller!.abort(callerSignal!.reason);\n callerSignal.addEventListener('abort', onCallerAbort, { once: true });\n controller.signal.addEventListener(\n 'abort',\n () => {\n callerSignal!.removeEventListener('abort', onCallerAbort);\n },\n { once: true },\n );\n }\n }\n }\n\n try {\n const response = await this.fetch(url, {\n method,\n headers: requestHeaders,\n body: processedBody,\n ...fetchOptions,\n ...(controller ? { signal: controller.signal } : {}),\n });\n\n if (this.isRetryableStatus(response.status) && attempt < maxAttempts) {\n if (timer !== undefined) clearTimeout(timer);\n await response.body?.cancel();\n lastError = new MitwayBaasError(\n `Server error: ${response.status} ${response.statusText}`,\n response.status,\n 'SERVER_ERROR',\n );\n continue;\n }\n\n if (response.status === 204) {\n if (timer !== undefined) clearTimeout(timer);\n return undefined as T;\n }\n\n let data: any;\n const contentType = response.headers.get('content-type');\n try {\n if (contentType?.includes('json')) {\n data = await response.json();\n } else {\n data = await response.text();\n }\n } catch (parseErr: any) {\n if (timer !== undefined) clearTimeout(timer);\n throw new MitwayBaasError(\n `Failed to parse response body: ${parseErr?.message || 'Unknown error'}`,\n response.status,\n response.ok ? 'PARSE_ERROR' : 'REQUEST_FAILED',\n );\n }\n\n if (timer !== undefined) clearTimeout(timer);\n\n if (!response.ok) {\n this.logger.logResponse(\n method,\n url,\n response.status,\n Date.now() - startTime,\n data,\n );\n if (data && typeof data === 'object' && 'error' in data) {\n if (!data.statusCode && !data.status) {\n data.statusCode = response.status;\n }\n const error = MitwayBaasError.fromApiError(data as ApiError);\n Object.keys(data).forEach((key) => {\n if (key !== 'error' && key !== 'message' && key !== 'statusCode') {\n (error as any)[key] = data[key];\n }\n });\n throw error;\n }\n throw new MitwayBaasError(\n `Request failed: ${response.statusText}`,\n response.status,\n 'REQUEST_FAILED',\n );\n }\n\n this.logger.logResponse(\n method,\n url,\n response.status,\n Date.now() - startTime,\n data,\n );\n return data as T;\n } catch (err: any) {\n if (timer !== undefined) clearTimeout(timer);\n\n if (err?.name === 'AbortError') {\n if (\n controller &&\n controller.signal.aborted &&\n this.timeout > 0 &&\n !callerSignal?.aborted\n ) {\n throw new MitwayBaasError(\n `Request timed out after ${this.timeout}ms`,\n 408,\n 'REQUEST_TIMEOUT',\n );\n }\n throw err;\n }\n\n if (err instanceof MitwayBaasError) {\n throw err;\n }\n\n if (attempt < maxAttempts) {\n lastError = err;\n continue;\n }\n\n throw new MitwayBaasError(\n `Network request failed: ${err?.message || 'Unknown error'}`,\n 0,\n 'NETWORK_ERROR',\n );\n }\n }\n\n throw (\n lastError ||\n new MitwayBaasError(\n 'Request failed after all retry attempts',\n 0,\n 'NETWORK_ERROR',\n )\n );\n }\n\n async request<T>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n try {\n return await this.handleRequest<T>(method, path, { ...options });\n } catch (error) {\n if (\n error instanceof MitwayBaasError &&\n error.statusCode === 401 &&\n error.error === 'INVALID_TOKEN' &&\n this.autoRefreshToken\n ) {\n try {\n const newTokenData = await this.handleTokenRefresh();\n this.setAuthToken(newTokenData.accessToken);\n this.tokenManager!.saveSession(newTokenData);\n if (newTokenData.csrfToken) {\n setCsrfToken(newTokenData.csrfToken);\n }\n if (newTokenData.refreshToken) {\n this.setRefreshToken(newTokenData.refreshToken);\n }\n return await this.handleRequest<T>(method, path, { ...options });\n } catch (refreshError) {\n this.tokenManager.clearSession();\n this.userToken = null;\n this.refreshToken = null;\n clearCsrfToken();\n throw refreshError;\n }\n }\n throw error;\n }\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 this.userToken = token;\n }\n\n setRefreshToken(token: string | null) {\n this.refreshToken = token;\n }\n\n getHeaders(): Record<string, string> {\n const headers = { ...this.defaultHeaders };\n const authToken = this.userToken || this.anonKey;\n if (authToken) {\n headers['Authorization'] = `Bearer ${authToken}`;\n }\n return headers;\n }\n\n /**\n * Refresh the current session by calling the MITWAY-BaaS refresh endpoint.\n * Note: the route is `/api/auth/refresh` (POST), not the InsForge\n * `/api/auth/sessions/current` route. Returns the new access token + user.\n */\n async handleTokenRefresh(): Promise<AuthRefreshResponse> {\n if (this.isRefreshing) {\n return this.refreshPromise!;\n }\n\n this.isRefreshing = true;\n this.refreshPromise = (async () => {\n try {\n const csrfToken = getCsrfToken();\n const body = this.refreshToken\n ? { refreshToken: this.refreshToken }\n : undefined;\n const response = await this.handleRequest<AuthRefreshResponse>(\n 'POST',\n '/api/auth/refresh',\n {\n body,\n headers: csrfToken ? { 'X-CSRF-Token': csrfToken } : {},\n credentials: 'include',\n },\n );\n return response;\n } finally {\n this.isRefreshing = false;\n this.refreshPromise = null;\n }\n })();\n\n return this.refreshPromise;\n }\n}\n","/**\n * Auth module — MITWAY-BaaS specific.\n *\n * Targets the routes that the MITWAY-BaaS backend currently exposes:\n * POST /api/auth/register → signUp\n * POST /api/auth/login → signInWithPassword\n * POST /api/auth/logout → signOut\n * POST /api/auth/refresh → refreshSession (also auto-called by HttpClient)\n *\n * OAuth, email verification, password reset, and the InsForge-only\n * profile/sessions admin endpoints are NOT included — the backend does not\n * implement them yet. When it does, port the corresponding methods from the\n * upstream InsForge SDK (`InsForge/InsForge-sdk-js/src/modules/auth/auth.ts`).\n */\n\nimport type { User } from '../lib/user';\nimport { HttpClient } from '../lib/http-client';\nimport { TokenManager, setCsrfToken, clearCsrfToken } from '../lib/token-manager';\nimport { AuthSession, MitwayBaasError } from '../types';\n\nexport interface SignUpRequest {\n email: string;\n password: string;\n name?: string;\n}\n\nexport interface SignInRequest {\n email: string;\n password: string;\n}\n\n/**\n * The shape the backend returns from /register, /login, and /refresh. Mirrors\n * what the existing backend handlers send: `{ user, accessToken, refreshToken,\n * csrfToken? }` wrapped in the standard `{ data, error }` envelope. The SDK\n * unwraps the envelope before reaching this type, so consumers see the raw\n * shape.\n */\nexport interface AuthResponse {\n user: User;\n accessToken: string;\n refreshToken?: string;\n csrfToken?: string;\n}\n\nexport type AuthResult<T> = {\n data: T | null;\n error: MitwayBaasError | null;\n};\n\nfunction wrapError<T>(error: unknown, fallbackMessage: string): AuthResult<T> {\n if (error instanceof MitwayBaasError) {\n return { data: null, error };\n }\n return {\n data: null,\n error: new MitwayBaasError(\n error instanceof Error ? error.message : fallbackMessage,\n 500,\n 'AUTH_ERROR',\n ),\n };\n}\n\nexport class Auth {\n constructor(\n private http: HttpClient,\n private tokenManager: TokenManager,\n ) {}\n\n /**\n * Persist the session in memory + HttpClient defaults so subsequent\n * requests carry the new bearer token automatically.\n */\n private saveSessionFromResponse(response: AuthResponse): void {\n const session: AuthSession = {\n accessToken: response.accessToken,\n user: response.user,\n };\n if (response.csrfToken) {\n setCsrfToken(response.csrfToken);\n }\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(response.accessToken);\n this.http.setRefreshToken(response.refreshToken ?? null);\n }\n\n /**\n * Create a new user account and start a session.\n *\n * @example\n * const { data, error } = await client.auth.signUp({\n * email: 'a@b.com',\n * password: 'a-strong-password',\n * name: 'Alice'\n * });\n */\n async signUp(request: SignUpRequest): Promise<AuthResult<AuthResponse>> {\n try {\n const response = await this.http.post<AuthResponse>(\n '/api/auth/register',\n request,\n { credentials: 'include' },\n );\n if (response?.accessToken && response.user) {\n this.saveSessionFromResponse(response);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<AuthResponse>(error, 'Sign up failed');\n }\n }\n\n /**\n * Sign in with email + password and start a session.\n */\n async signInWithPassword(\n request: SignInRequest,\n ): Promise<AuthResult<AuthResponse>> {\n try {\n const response = await this.http.post<AuthResponse>(\n '/api/auth/login',\n request,\n { credentials: 'include' },\n );\n if (response?.accessToken && response.user) {\n this.saveSessionFromResponse(response);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<AuthResponse>(error, 'Sign in failed');\n }\n }\n\n /**\n * End the current session. Clears in-memory state even if the backend\n * call fails (network/offline).\n */\n async signOut(): Promise<{ error: MitwayBaasError | null }> {\n try {\n try {\n await this.http.post('/api/auth/logout', undefined, {\n credentials: 'include',\n });\n } catch {\n // Backend logout failure is non-fatal — local state still clears.\n }\n this.tokenManager.clearSession();\n this.http.setAuthToken(null);\n this.http.setRefreshToken(null);\n clearCsrfToken();\n return { error: null };\n } catch {\n return {\n error: new MitwayBaasError('Failed to sign out', 500, 'SIGNOUT_ERROR'),\n };\n }\n }\n\n /**\n * Manually refresh the current session. The HttpClient will call this\n * automatically on 401 INVALID_TOKEN responses; consumers usually do\n * not need to call it directly.\n */\n async refreshSession(): Promise<AuthResult<AuthResponse>> {\n try {\n const response = await this.http.handleTokenRefresh();\n if (response?.accessToken && response.user) {\n this.saveSessionFromResponse(response);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<AuthResponse>(error, 'Session refresh failed');\n }\n }\n\n /**\n * Get the current in-memory session, or null if the user is not signed in.\n * Synchronous — does not hit the network.\n */\n getSession(): AuthSession | null {\n return this.tokenManager.getSession();\n }\n\n /**\n * Get the current in-memory user, or null if not signed in.\n */\n getUser(): User | null {\n return this.tokenManager.getUser();\n }\n}\n","/**\n * Database module — wraps `@supabase/postgrest-js` and points it directly\n * at the per-cliente PostgREST instance.\n *\n * Why direct (not via the backend like InsForge does):\n * - InsForge's SDK proxies through `/api/database/records/{table}` on the\n * backend, which then forwards to PostgREST internally. MITWAY-BaaS does\n * not have that proxy route — PostgREST is its own Pod in the per-cliente\n * namespace and is reached directly via its own Service / public ingress.\n * - Talking directly avoids a hop through the backend and keeps the SDK\n * simple. The downside is that the consumer has to know two URLs (the\n * backend baseUrl and the PostgREST URL), which is what\n * `MitwayBaasConfig.postgrestUrl` is for.\n *\n * Auth: the SDK forwards the in-memory access token from the TokenManager\n * as `Authorization: Bearer <jwt>`. PostgREST verifies the JWT with the\n * tenant's JWT_SECRET (the same secret the backend uses, configured via the\n * helm chart secret).\n */\n\nimport { PostgrestClient } from '@supabase/postgrest-js';\nimport { TokenManager } from '../lib/token-manager';\nimport { MitwayBaasError } from '../types';\n\n/**\n * Create a fetch wrapper that injects the current access token (or the\n * anon key fallback) on every PostgREST request. The token is read from\n * the TokenManager on each request, so a sign-in/sign-out picks up\n * automatically without re-creating the client.\n */\nfunction createAuthedFetch(\n tokenManager: TokenManager,\n anonKey: string | undefined,\n): typeof fetch {\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const headers = new Headers(init?.headers);\n if (!headers.has('Authorization')) {\n const token = tokenManager.getAccessToken() ?? anonKey;\n if (token) {\n headers.set('Authorization', `Bearer ${token}`);\n }\n }\n return fetch(input as any, { ...init, headers });\n };\n}\n\nexport class Database {\n private postgrest: PostgrestClient<any, any, any> | null;\n private postgrestUrl: string | undefined;\n\n constructor(\n tokenManager: TokenManager,\n postgrestUrl: string | undefined,\n anonKey: string | undefined,\n ) {\n this.postgrestUrl = postgrestUrl;\n if (postgrestUrl) {\n this.postgrest = new PostgrestClient<any, any, any>(postgrestUrl, {\n fetch: createAuthedFetch(tokenManager, anonKey),\n headers: {},\n });\n } else {\n this.postgrest = null;\n }\n }\n\n private requireClient(): PostgrestClient<any, any, any> {\n if (!this.postgrest) {\n throw new MitwayBaasError(\n 'Database is not configured. Pass `postgrestUrl` in the SDK config to enable database operations.',\n 500,\n 'DATABASE_NOT_CONFIGURED',\n );\n }\n return this.postgrest;\n }\n\n /**\n * Build a PostgREST query against a table.\n *\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 * @example\n * const { data, error } = await client.database\n * .from('posts')\n * .insert({ title: 'Hello', content: 'World' })\n * .select()\n * .single();\n */\n from(table: string) {\n return this.requireClient().from(table);\n }\n\n /**\n * Call a PostgreSQL stored function (RPC).\n *\n * @example\n * const { data, error } = await client.database\n * .rpc('get_user_stats', { user_id: 123 });\n */\n rpc(\n fn: string,\n args?: Record<string, unknown>,\n options?: { head?: boolean; get?: boolean; count?: 'exact' | 'planned' | 'estimated' },\n ) {\n return this.requireClient().rpc(fn, args, options);\n }\n\n /**\n * The PostgREST URL the database client is talking to, or undefined if\n * the database module is not configured.\n */\n getUrl(): string | undefined {\n return this.postgrestUrl;\n }\n}\n","import { MitwayBaasConfig } from './types';\nimport { HttpClient } from './lib/http-client';\nimport { Logger } from './lib/logger';\nimport { TokenManager } from './lib/token-manager';\nimport { Auth } from './modules/auth';\nimport { Database } from './modules/database';\n\n/**\n * MITWAY-BaaS SDK client.\n *\n * @example\n * ```typescript\n * import { createClient } from '@mitway-baas/sdk';\n *\n * const client = createClient({\n * baseUrl: 'https://acme.api.dev.nttmitway.com', // backend (auth)\n * postgrestUrl: 'https://acme.db.dev.nttmitway.com', // postgrest (db)\n * anonKey: 'eyJhbGciOiJIUzI1NiIs...', // optional\n * });\n *\n * // Auth\n * const { data: session, error } = await client.auth.signInWithPassword({\n * email: 'a@b.com',\n * password: 'pw',\n * });\n *\n * // Database\n * const { data, error: dbError } = await client.database\n * .from('posts')\n * .select('*')\n * .eq('user_id', session.user.id)\n * .order('created_at', { ascending: false });\n * ```\n */\nexport class MitwayBaasClient {\n private http: HttpClient;\n private tokenManager: TokenManager;\n public readonly auth: Auth;\n public readonly database: Database;\n\n constructor(config: MitwayBaasConfig = {}) {\n const logger = new Logger(config.debug);\n this.tokenManager = new TokenManager();\n this.http = new HttpClient(config, this.tokenManager, logger);\n this.auth = new Auth(this.http, this.tokenManager);\n this.database = new Database(this.tokenManager, config.postgrestUrl, config.anonKey);\n }\n\n /**\n * Escape hatch for callers that need to make custom requests against the\n * backend without going through `auth` or `database`.\n */\n getHttpClient(): HttpClient {\n return this.http;\n }\n}\n"],"mappings":"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","names":["timer"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/lib/logger.ts","../src/lib/token-manager.ts","../src/lib/http-client.ts","../src/modules/auth.ts","../src/modules/database.ts","../src/client.ts"],"sourcesContent":["/**\n * @mitway-baas/sdk — TypeScript SDK for the MITWAY-BaaS backend.\n *\n * Currently ships:\n * - auth (signUp, signInWithPassword, signOut, refreshSession, getSession, getUser)\n * - database (PostgREST-backed query builder via @supabase/postgrest-js)\n *\n * Not yet included (no backend support):\n * - storage\n * - functions\n * - email\n * - ai\n * - realtime\n *\n * @packageDocumentation\n */\n\nexport { MitwayBaasClient } from './client';\n\nimport { MitwayBaasClient } from './client';\nimport { MitwayBaasConfig } from './types';\n\n/**\n * Factory function for creating SDK clients (Supabase-style).\n *\n * @example\n * ```typescript\n * import { createClient } from '@mitway-baas/sdk';\n *\n * const client = createClient({\n * baseUrl: 'https://acme.api.dev.nttmitway.com',\n * postgrestUrl: 'https://acme.db.dev.nttmitway.com',\n * });\n * ```\n */\nexport function createClient(config: MitwayBaasConfig): MitwayBaasClient {\n return new MitwayBaasClient(config);\n}\n\n// Default export for `import client from '@mitway-baas/sdk'`\nexport default MitwayBaasClient;\n\n// Public types\nexport type {\n MitwayBaasConfig,\n AuthSession,\n AuthRefreshResponse,\n ApiError,\n} from './types';\nexport { MitwayBaasError } from './types';\n\n// Re-export module classes for advanced/TypeScript-friendly usage\nexport { Auth } from './modules/auth';\nexport type { SignUpRequest, SignInRequest, AuthResponse, AuthResult } from './modules/auth';\nexport { Database } from './modules/database';\n\n// Re-export low-level helpers (most consumers won't need these)\nexport { HttpClient } from './lib/http-client';\nexport { TokenManager } from './lib/token-manager';\nexport { Logger } from './lib/logger';\n\n// Public User shape — inlined in lib/user so this package has no\n// MITWAY-BaaS workspace dependencies.\nexport type { User } from './lib/user';\n","/**\n * MITWAY-BaaS SDK types — only SDK-specific shapes live here.\n * The `User` shape is inlined in `./lib/user` so this package has zero\n * MITWAY-BaaS workspace dependencies.\n */\n\nimport type { User } from './lib/user';\n\nexport interface MitwayBaasConfig {\n /**\n * Base URL of the MITWAY-BaaS backend. In production this is typically\n * `https://{cliente}.api.dev.nttmitway.com` (or the equivalent pro\n * domain). The SDK routes all traffic — auth, database (via the\n * backend's PostgREST proxy at `/api/database/records/*`), and future\n * storage/functions — through this one URL.\n *\n * @default \"http://localhost:7130\"\n */\n baseUrl?: string;\n\n /**\n * Anonymous JWT (signed by the tenant's JWT_SECRET, role = \"anon\").\n * Used as a fallback Bearer token for unauthenticated requests when no\n * user session is active.\n */\n anonKey?: string;\n\n /**\n * Custom fetch implementation. Useful in Node < 18 or test environments.\n * Defaults to `globalThis.fetch`.\n */\n fetch?: typeof fetch;\n\n /**\n * Custom default headers included on every request.\n */\n headers?: Record<string, string>;\n\n /**\n * Enable debug logging. `true` logs to console; pass a function to receive\n * log lines instead.\n */\n debug?: boolean | ((message: string, ...args: any[]) => void);\n\n /**\n * Per-request timeout in milliseconds. 0 disables the timeout.\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Number of retry attempts on network errors and 5xx responses. Client\n * errors (4xx) are never retried. 0 disables retries.\n * @default 3\n */\n retryCount?: number;\n\n /**\n * Initial delay before the first retry, in ms. Doubles each attempt with\n * ±15% jitter.\n * @default 500\n */\n retryDelay?: number;\n\n /**\n * Automatically refresh the access token on 401 INVALID_TOKEN responses\n * and retry the original request.\n * @default true\n */\n autoRefreshToken?: boolean;\n}\n\n/**\n * Active user session in memory. Mirrors what the auth endpoints return.\n */\nexport interface AuthSession {\n user: User;\n accessToken: string;\n expiresAt?: Date;\n}\n\n/**\n * Minimal payload that auth refresh endpoints emit. The SDK uses this to\n * refresh the in-memory session.\n */\nexport interface AuthRefreshResponse {\n user: User;\n accessToken: string;\n refreshToken?: string;\n csrfToken?: string;\n}\n\n/**\n * The `{ data, error }` envelope used by the MITWAY-BaaS backend on every\n * response. The SDK unwraps `data` for happy-path returns and converts\n * `error` into a `MitwayBaasError`.\n */\nexport interface ApiError {\n error: string;\n message: string;\n statusCode: number;\n nextActions?: string;\n}\n\nexport class MitwayBaasError extends Error {\n public statusCode: number;\n public error: string;\n public nextActions?: string;\n\n constructor(\n message: string,\n statusCode: number,\n error: string,\n nextActions?: string,\n ) {\n super(message);\n this.name = 'MitwayBaasError';\n this.statusCode = statusCode;\n this.error = error;\n this.nextActions = nextActions;\n }\n\n static fromApiError(apiError: ApiError): MitwayBaasError {\n return new MitwayBaasError(\n apiError.message,\n apiError.statusCode,\n apiError.error,\n apiError.nextActions,\n );\n }\n}\n","/**\n * Debug logger for the MITWAY-BaaS SDK.\n *\n * Logs HTTP request/response details with automatic redaction of sensitive\n * headers and body fields. Disabled by default; pass `debug: true` (or a\n * custom log function) on the SDK config to enable.\n */\n\ntype LogFunction = (message: string, ...args: any[]) => void;\n\nconst SENSITIVE_HEADERS = ['authorization', 'x-api-key', 'cookie', 'set-cookie'];\n\nconst SENSITIVE_BODY_KEYS = [\n 'password', 'token', 'accesstoken', 'refreshtoken',\n 'authorization', 'secret', 'apikey', 'api_key',\n 'email', 'ssn', 'creditcard', 'credit_card',\n];\n\nfunction redactHeaders(headers: Record<string, string>): Record<string, string> {\n const redacted: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (SENSITIVE_HEADERS.includes(key.toLowerCase())) {\n redacted[key] = '***REDACTED***';\n } else {\n redacted[key] = value;\n }\n }\n return redacted;\n}\n\nfunction sanitizeBody(body: any): any {\n if (body === null || body === undefined) return body;\n if (typeof body === 'string') {\n try {\n const parsed = JSON.parse(body);\n return sanitizeBody(parsed);\n } catch {\n return body;\n }\n }\n if (Array.isArray(body)) return body.map(sanitizeBody);\n if (typeof body === 'object') {\n const sanitized: Record<string, any> = {};\n for (const [key, value] of Object.entries(body)) {\n if (SENSITIVE_BODY_KEYS.includes(key.toLowerCase().replace(/[-_]/g, ''))) {\n sanitized[key] = '***REDACTED***';\n } else {\n sanitized[key] = sanitizeBody(value);\n }\n }\n return sanitized;\n }\n return body;\n}\n\nfunction formatBody(body: any): string {\n if (body === undefined || body === null) return '';\n if (typeof body === 'string') {\n try {\n return JSON.stringify(JSON.parse(body), null, 2);\n } catch {\n return body;\n }\n }\n if (typeof FormData !== 'undefined' && body instanceof FormData) {\n return '[FormData]';\n }\n try {\n return JSON.stringify(body, null, 2);\n } catch {\n return '[Unserializable body]';\n }\n}\n\nexport class Logger {\n public enabled: boolean;\n private customLog: LogFunction | null;\n\n constructor(debug?: boolean | LogFunction) {\n if (typeof debug === 'function') {\n this.enabled = true;\n this.customLog = debug;\n } else {\n this.enabled = !!debug;\n this.customLog = null;\n }\n }\n\n log(message: string, ...args: any[]): void {\n if (!this.enabled) return;\n const formatted = `[MITWAY-BaaS Debug] ${message}`;\n if (this.customLog) {\n this.customLog(formatted, ...args);\n } else {\n console.log(formatted, ...args);\n }\n }\n\n warn(message: string, ...args: any[]): void {\n if (!this.enabled) return;\n const formatted = `[MITWAY-BaaS Debug] ${message}`;\n if (this.customLog) {\n this.customLog(formatted, ...args);\n } else {\n console.warn(formatted, ...args);\n }\n }\n\n error(message: string, ...args: any[]): void {\n if (!this.enabled) return;\n const formatted = `[MITWAY-BaaS Debug] ${message}`;\n if (this.customLog) {\n this.customLog(formatted, ...args);\n } else {\n console.error(formatted, ...args);\n }\n }\n\n logRequest(\n method: string,\n url: string,\n headers?: Record<string, string>,\n body?: any\n ): void {\n if (!this.enabled) return;\n const parts: string[] = [`→ ${method} ${url}`];\n if (headers && Object.keys(headers).length > 0) {\n parts.push(` Headers: ${JSON.stringify(redactHeaders(headers))}`);\n }\n const formattedBody = formatBody(sanitizeBody(body));\n if (formattedBody) {\n const truncated = formattedBody.length > 1000\n ? formattedBody.slice(0, 1000) + '... [truncated]'\n : formattedBody;\n parts.push(` Body: ${truncated}`);\n }\n this.log(parts.join('\\n'));\n }\n\n logResponse(\n method: string,\n url: string,\n status: number,\n durationMs: number,\n body?: any\n ): void {\n if (!this.enabled) return;\n const parts: string[] = [\n `← ${method} ${url} ${status} (${durationMs}ms)`,\n ];\n const formattedBody = formatBody(sanitizeBody(body));\n if (formattedBody) {\n const truncated = formattedBody.length > 1000\n ? formattedBody.slice(0, 1000) + '... [truncated]'\n : formattedBody;\n parts.push(` Body: ${truncated}`);\n }\n if (status >= 400) {\n this.error(parts.join('\\n'));\n } else {\n this.log(parts.join('\\n'));\n }\n }\n}\n","/**\n * Token Manager for the MITWAY-BaaS SDK.\n *\n * In-memory storage for the access token + user. Browser CSRF token lives\n * in a cookie so the cookie-based refresh flow works across page reloads.\n */\n\nimport type { User } from './user';\nimport type { AuthSession } from '../types';\n\nexport const CSRF_TOKEN_COOKIE = 'mitway_baas_csrf_token';\n\nexport function getCsrfToken(): string | null {\n if (typeof document === 'undefined') return null;\n const match = document.cookie\n .split(';')\n .find((c) => c.trim().startsWith(`${CSRF_TOKEN_COOKIE}=`));\n if (!match) return null;\n return match.split('=')[1] || null;\n}\n\nexport function setCsrfToken(token: string): void {\n if (typeof document === 'undefined') return;\n const maxAge = 7 * 24 * 60 * 60; // 7 days\n const secure =\n typeof window !== 'undefined' && window.location.protocol === 'https:'\n ? '; Secure'\n : '';\n document.cookie = `${CSRF_TOKEN_COOKIE}=${encodeURIComponent(token)}; path=/; max-age=${maxAge}; SameSite=Lax${secure}`;\n}\n\nexport function clearCsrfToken(): void {\n if (typeof document === 'undefined') return;\n const secure =\n typeof window !== 'undefined' && window.location.protocol === 'https:'\n ? '; Secure'\n : '';\n document.cookie = `${CSRF_TOKEN_COOKIE}=; path=/; max-age=0; SameSite=Lax${secure}`;\n}\n\nexport class TokenManager {\n private accessToken: string | null = null;\n private user: User | null = null;\n\n /** Fired when the access token changes (used by long-lived consumers). */\n onTokenChange: (() => void) | null = null;\n\n saveSession(session: AuthSession): void {\n const tokenChanged = session.accessToken !== this.accessToken;\n this.accessToken = session.accessToken;\n this.user = session.user;\n if (tokenChanged && this.onTokenChange) {\n this.onTokenChange();\n }\n }\n\n getSession(): AuthSession | null {\n if (!this.accessToken || !this.user) return null;\n return {\n accessToken: this.accessToken,\n user: this.user,\n };\n }\n\n getAccessToken(): string | null {\n return this.accessToken;\n }\n\n setAccessToken(token: string): void {\n const tokenChanged = token !== this.accessToken;\n this.accessToken = token;\n if (tokenChanged && this.onTokenChange) {\n this.onTokenChange();\n }\n }\n\n getUser(): User | null {\n return this.user;\n }\n\n setUser(user: User): void {\n this.user = user;\n }\n\n clearSession(): void {\n const hadToken = this.accessToken !== null;\n this.accessToken = null;\n this.user = null;\n if (hadToken && this.onTokenChange) {\n this.onTokenChange();\n }\n }\n}\n","/**\n * HttpClient with retry, timeout, abort signal composition, and automatic\n * token refresh on 401 INVALID_TOKEN responses.\n *\n * Ported from the InsForge SDK with rebranding plus one route change:\n * the refresh endpoint is `/api/auth/refresh` (MITWAY-BaaS) instead of\n * `/api/auth/sessions/current` (InsForge).\n */\n\nimport {\n MitwayBaasConfig,\n ApiError,\n MitwayBaasError,\n AuthRefreshResponse,\n} from '../types';\nimport { Logger } from './logger';\nimport {\n clearCsrfToken,\n getCsrfToken,\n setCsrfToken,\n TokenManager,\n} from './token-manager';\n\ntype JsonRequestBody = Record<string, unknown> | unknown[] | null;\n\nexport interface RequestOptions extends Omit<RequestInit, 'body'> {\n params?: Record<string, string>;\n body?: RequestInit['body'] | JsonRequestBody;\n /**\n * Allow retrying non-idempotent requests (POST, PATCH). Off by default to\n * prevent duplicate writes on transient server errors.\n */\n idempotent?: boolean;\n}\n\nconst RETRYABLE_STATUS_CODES = new Set([500, 502, 503, 504]);\nconst IDEMPOTENT_METHODS = new Set(['GET', 'HEAD', 'PUT', 'DELETE', 'OPTIONS']);\n\nexport class HttpClient {\n public readonly baseUrl: string;\n public readonly fetch: typeof fetch;\n private defaultHeaders: Record<string, string>;\n private anonKey: string | undefined;\n private userToken: string | null = null;\n private logger: Logger;\n private autoRefreshToken: boolean = true;\n private isRefreshing: boolean = false;\n private refreshPromise: Promise<AuthRefreshResponse> | null = null;\n private tokenManager: TokenManager;\n private refreshToken: string | null = null;\n private timeout: number;\n private retryCount: number;\n private retryDelay: number;\n\n constructor(\n config: MitwayBaasConfig,\n tokenManager?: TokenManager,\n logger?: Logger,\n ) {\n this.baseUrl = config.baseUrl || 'http://localhost:7130';\n this.autoRefreshToken = config.autoRefreshToken ?? true;\n this.fetch =\n config.fetch ||\n (globalThis.fetch\n ? globalThis.fetch.bind(globalThis)\n : (undefined as any));\n this.anonKey = config.anonKey;\n this.defaultHeaders = {\n ...config.headers,\n };\n this.tokenManager = tokenManager ?? new TokenManager();\n this.logger = logger || new Logger(false);\n this.timeout = config.timeout ?? 30_000;\n this.retryCount = config.retryCount ?? 3;\n this.retryDelay = config.retryDelay ?? 500;\n\n if (!this.fetch) {\n throw new Error(\n 'Fetch is not available. Provide a fetch implementation in the SDK 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 if (key === 'select') {\n // Normalize PostgREST select syntax (whitespace inside relationships).\n let normalizedValue = value.replace(/\\s+/g, ' ').trim();\n normalizedValue = normalizedValue\n .replace(/\\s*\\(\\s*/g, '(')\n .replace(/\\s*\\)\\s*/g, ')')\n .replace(/\\(\\s+/g, '(')\n .replace(/\\s+\\)/g, ')')\n .replace(/,\\s+(?=[^()]*\\))/g, ',');\n url.searchParams.append(key, normalizedValue);\n } else {\n url.searchParams.append(key, value);\n }\n });\n }\n return url.toString();\n }\n\n private isRetryableStatus(status: number): boolean {\n return RETRYABLE_STATUS_CODES.has(status);\n }\n\n private computeRetryDelay(attempt: number): number {\n const base = this.retryDelay * Math.pow(2, attempt - 1);\n const jitter = base * (0.85 + Math.random() * 0.3);\n return Math.round(jitter);\n }\n\n private async handleRequest<T>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n const {\n params,\n headers = {},\n body,\n signal: callerSignal,\n ...fetchOptions\n } = options as RequestOptions & { signal?: AbortSignal };\n\n const url = this.buildUrl(path, params);\n const startTime = Date.now();\n const canRetry =\n IDEMPOTENT_METHODS.has(method.toUpperCase()) ||\n options.idempotent === true;\n const maxAttempts = canRetry ? this.retryCount : 0;\n\n const requestHeaders: Record<string, string> = {\n ...this.defaultHeaders,\n };\n\n const authToken = this.userToken || this.anonKey;\n if (authToken) {\n requestHeaders['Authorization'] = `Bearer ${authToken}`;\n }\n\n let processedBody: any;\n if (body !== undefined) {\n if (typeof FormData !== 'undefined' && body instanceof FormData) {\n processedBody = body;\n } else {\n if (method !== 'GET') {\n requestHeaders['Content-Type'] = 'application/json;charset=UTF-8';\n }\n processedBody = JSON.stringify(body);\n }\n }\n\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n requestHeaders[key] = value;\n });\n } else if (Array.isArray(headers)) {\n headers.forEach(([key, value]) => {\n requestHeaders[key] = value;\n });\n } else {\n Object.assign(requestHeaders, headers);\n }\n\n this.logger.logRequest(method, url, requestHeaders, processedBody);\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxAttempts; attempt++) {\n if (attempt > 0) {\n const delay = this.computeRetryDelay(attempt);\n this.logger.warn(\n `Retry ${attempt}/${maxAttempts} for ${method} ${url} in ${delay}ms`,\n );\n if (callerSignal?.aborted) throw callerSignal.reason;\n await new Promise<void>((resolve, reject) => {\n const onAbort = () => {\n clearTimeout(timer);\n reject(callerSignal!.reason);\n };\n const timer = setTimeout(() => {\n if (callerSignal)\n callerSignal.removeEventListener('abort', onAbort);\n resolve();\n }, delay);\n if (callerSignal) {\n callerSignal.addEventListener('abort', onAbort, { once: true });\n }\n });\n }\n\n let controller: AbortController | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n if (this.timeout > 0 || callerSignal) {\n controller = new AbortController();\n\n if (this.timeout > 0) {\n timer = setTimeout(() => controller!.abort(), this.timeout);\n }\n\n if (callerSignal) {\n if (callerSignal.aborted) {\n controller.abort(callerSignal.reason);\n } else {\n const onCallerAbort = () => controller!.abort(callerSignal!.reason);\n callerSignal.addEventListener('abort', onCallerAbort, { once: true });\n controller.signal.addEventListener(\n 'abort',\n () => {\n callerSignal!.removeEventListener('abort', onCallerAbort);\n },\n { once: true },\n );\n }\n }\n }\n\n try {\n const response = await this.fetch(url, {\n method,\n headers: requestHeaders,\n body: processedBody,\n ...fetchOptions,\n ...(controller ? { signal: controller.signal } : {}),\n });\n\n if (this.isRetryableStatus(response.status) && attempt < maxAttempts) {\n if (timer !== undefined) clearTimeout(timer);\n await response.body?.cancel();\n lastError = new MitwayBaasError(\n `Server error: ${response.status} ${response.statusText}`,\n response.status,\n 'SERVER_ERROR',\n );\n continue;\n }\n\n if (response.status === 204) {\n if (timer !== undefined) clearTimeout(timer);\n return undefined as T;\n }\n\n let data: any;\n const contentType = response.headers.get('content-type');\n try {\n if (contentType?.includes('json')) {\n data = await response.json();\n } else {\n data = await response.text();\n }\n } catch (parseErr: any) {\n if (timer !== undefined) clearTimeout(timer);\n throw new MitwayBaasError(\n `Failed to parse response body: ${parseErr?.message || 'Unknown error'}`,\n response.status,\n response.ok ? 'PARSE_ERROR' : 'REQUEST_FAILED',\n );\n }\n\n if (timer !== undefined) clearTimeout(timer);\n\n if (!response.ok) {\n this.logger.logResponse(\n method,\n url,\n response.status,\n Date.now() - startTime,\n data,\n );\n if (data && typeof data === 'object' && 'error' in data) {\n if (!data.statusCode && !data.status) {\n data.statusCode = response.status;\n }\n const error = MitwayBaasError.fromApiError(data as ApiError);\n Object.keys(data).forEach((key) => {\n if (key !== 'error' && key !== 'message' && key !== 'statusCode') {\n (error as any)[key] = data[key];\n }\n });\n throw error;\n }\n throw new MitwayBaasError(\n `Request failed: ${response.statusText}`,\n response.status,\n 'REQUEST_FAILED',\n );\n }\n\n this.logger.logResponse(\n method,\n url,\n response.status,\n Date.now() - startTime,\n data,\n );\n return data as T;\n } catch (err: any) {\n if (timer !== undefined) clearTimeout(timer);\n\n if (err?.name === 'AbortError') {\n if (\n controller &&\n controller.signal.aborted &&\n this.timeout > 0 &&\n !callerSignal?.aborted\n ) {\n throw new MitwayBaasError(\n `Request timed out after ${this.timeout}ms`,\n 408,\n 'REQUEST_TIMEOUT',\n );\n }\n throw err;\n }\n\n if (err instanceof MitwayBaasError) {\n throw err;\n }\n\n if (attempt < maxAttempts) {\n lastError = err;\n continue;\n }\n\n throw new MitwayBaasError(\n `Network request failed: ${err?.message || 'Unknown error'}`,\n 0,\n 'NETWORK_ERROR',\n );\n }\n }\n\n throw (\n lastError ||\n new MitwayBaasError(\n 'Request failed after all retry attempts',\n 0,\n 'NETWORK_ERROR',\n )\n );\n }\n\n async request<T>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n try {\n return await this.handleRequest<T>(method, path, { ...options });\n } catch (error) {\n if (\n error instanceof MitwayBaasError &&\n error.statusCode === 401 &&\n error.error === 'INVALID_TOKEN' &&\n this.autoRefreshToken\n ) {\n try {\n const newTokenData = await this.handleTokenRefresh();\n this.setAuthToken(newTokenData.accessToken);\n this.tokenManager!.saveSession(newTokenData);\n if (newTokenData.csrfToken) {\n setCsrfToken(newTokenData.csrfToken);\n }\n if (newTokenData.refreshToken) {\n this.setRefreshToken(newTokenData.refreshToken);\n }\n return await this.handleRequest<T>(method, path, { ...options });\n } catch (refreshError) {\n this.tokenManager.clearSession();\n this.userToken = null;\n this.refreshToken = null;\n clearCsrfToken();\n throw refreshError;\n }\n }\n throw error;\n }\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 this.userToken = token;\n }\n\n setRefreshToken(token: string | null) {\n this.refreshToken = token;\n }\n\n getHeaders(): Record<string, string> {\n const headers = { ...this.defaultHeaders };\n const authToken = this.userToken || this.anonKey;\n if (authToken) {\n headers['Authorization'] = `Bearer ${authToken}`;\n }\n return headers;\n }\n\n /**\n * Refresh the current session by calling the MITWAY-BaaS refresh endpoint.\n * Note: the route is `/api/auth/refresh` (POST), not the InsForge\n * `/api/auth/sessions/current` route. Returns the new access token + user.\n */\n async handleTokenRefresh(): Promise<AuthRefreshResponse> {\n if (this.isRefreshing) {\n return this.refreshPromise!;\n }\n\n this.isRefreshing = true;\n this.refreshPromise = (async () => {\n try {\n const csrfToken = getCsrfToken();\n const body = this.refreshToken\n ? { refreshToken: this.refreshToken }\n : undefined;\n const response = await this.handleRequest<AuthRefreshResponse>(\n 'POST',\n '/api/auth/refresh',\n {\n body,\n headers: csrfToken ? { 'X-CSRF-Token': csrfToken } : {},\n credentials: 'include',\n },\n );\n return response;\n } finally {\n this.isRefreshing = false;\n this.refreshPromise = null;\n }\n })();\n\n return this.refreshPromise;\n }\n}\n","/**\n * Auth module — MITWAY-BaaS specific.\n *\n * Targets the routes that the MITWAY-BaaS backend currently exposes:\n * POST /api/auth/register → signUp\n * POST /api/auth/login → signInWithPassword\n * POST /api/auth/logout → signOut\n * POST /api/auth/refresh → refreshSession (also auto-called by HttpClient)\n *\n * OAuth, email verification, password reset, and the InsForge-only\n * profile/sessions admin endpoints are NOT included — the backend does not\n * implement them yet. When it does, port the corresponding methods from the\n * upstream InsForge SDK (`InsForge/InsForge-sdk-js/src/modules/auth/auth.ts`).\n */\n\nimport type { User } from '../lib/user';\nimport { HttpClient } from '../lib/http-client';\nimport { TokenManager, setCsrfToken, clearCsrfToken } from '../lib/token-manager';\nimport { AuthSession, MitwayBaasError } from '../types';\n\nexport interface SignUpRequest {\n email: string;\n password: string;\n name?: string;\n}\n\nexport interface SignInRequest {\n email: string;\n password: string;\n}\n\n/**\n * The shape the backend returns from /register, /login, and /refresh. Mirrors\n * what the existing backend handlers send: `{ user, accessToken, refreshToken,\n * csrfToken? }` wrapped in the standard `{ data, error }` envelope. The SDK\n * unwraps the envelope before reaching this type, so consumers see the raw\n * shape.\n */\nexport interface AuthResponse {\n user: User;\n accessToken: string;\n refreshToken?: string;\n csrfToken?: string;\n}\n\nexport type AuthResult<T> = {\n data: T | null;\n error: MitwayBaasError | null;\n};\n\nfunction wrapError<T>(error: unknown, fallbackMessage: string): AuthResult<T> {\n if (error instanceof MitwayBaasError) {\n return { data: null, error };\n }\n return {\n data: null,\n error: new MitwayBaasError(\n error instanceof Error ? error.message : fallbackMessage,\n 500,\n 'AUTH_ERROR',\n ),\n };\n}\n\nexport class Auth {\n constructor(\n private http: HttpClient,\n private tokenManager: TokenManager,\n ) {}\n\n /**\n * Persist the session in memory + HttpClient defaults so subsequent\n * requests carry the new bearer token automatically.\n */\n private saveSessionFromResponse(response: AuthResponse): void {\n const session: AuthSession = {\n accessToken: response.accessToken,\n user: response.user,\n };\n if (response.csrfToken) {\n setCsrfToken(response.csrfToken);\n }\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(response.accessToken);\n this.http.setRefreshToken(response.refreshToken ?? null);\n }\n\n /**\n * Create a new user account and start a session.\n *\n * @example\n * const { data, error } = await client.auth.signUp({\n * email: 'a@b.com',\n * password: 'a-strong-password',\n * name: 'Alice'\n * });\n */\n async signUp(request: SignUpRequest): Promise<AuthResult<AuthResponse>> {\n try {\n const response = await this.http.post<AuthResponse>(\n '/api/auth/register',\n request,\n { credentials: 'include' },\n );\n if (response?.accessToken && response.user) {\n this.saveSessionFromResponse(response);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<AuthResponse>(error, 'Sign up failed');\n }\n }\n\n /**\n * Sign in with email + password and start a session.\n */\n async signInWithPassword(\n request: SignInRequest,\n ): Promise<AuthResult<AuthResponse>> {\n try {\n const response = await this.http.post<AuthResponse>(\n '/api/auth/login',\n request,\n { credentials: 'include' },\n );\n if (response?.accessToken && response.user) {\n this.saveSessionFromResponse(response);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<AuthResponse>(error, 'Sign in failed');\n }\n }\n\n /**\n * End the current session. Clears in-memory state even if the backend\n * call fails (network/offline).\n */\n async signOut(): Promise<{ error: MitwayBaasError | null }> {\n try {\n try {\n await this.http.post('/api/auth/logout', undefined, {\n credentials: 'include',\n });\n } catch {\n // Backend logout failure is non-fatal — local state still clears.\n }\n this.tokenManager.clearSession();\n this.http.setAuthToken(null);\n this.http.setRefreshToken(null);\n clearCsrfToken();\n return { error: null };\n } catch {\n return {\n error: new MitwayBaasError('Failed to sign out', 500, 'SIGNOUT_ERROR'),\n };\n }\n }\n\n /**\n * Manually refresh the current session. The HttpClient will call this\n * automatically on 401 INVALID_TOKEN responses; consumers usually do\n * not need to call it directly.\n */\n async refreshSession(): Promise<AuthResult<AuthResponse>> {\n try {\n const response = await this.http.handleTokenRefresh();\n if (response?.accessToken && response.user) {\n this.saveSessionFromResponse(response);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<AuthResponse>(error, 'Session refresh failed');\n }\n }\n\n /**\n * Get the current in-memory session, or null if the user is not signed in.\n * Synchronous — does not hit the network.\n */\n getSession(): AuthSession | null {\n return this.tokenManager.getSession();\n }\n\n /**\n * Get the current in-memory user, or null if not signed in.\n */\n getUser(): User | null {\n return this.tokenManager.getUser();\n }\n}\n","/**\n * Database module — wraps `@supabase/postgrest-js` and transforms its\n * outbound URLs so they hit the MITWAY-BaaS backend proxy instead of\n * PostgREST directly.\n *\n * Why via the backend (not direct to PostgREST):\n * PostgREST is deployed as an internal ClusterIP Service per cliente\n * (`mitway-baas-{cliente}-postgrest:3000`), never publicly exposed. The\n * backend forwards incoming `/api/database/records/*` and\n * `/api/database/rpc/*` requests to PostgREST over the cluster network.\n * This collapses the per-cliente public surface into a single URL:\n * `https://{cliente}.api.dev.nttmitway.com`.\n *\n * The pattern is copied from the InsForge SDK's `database-postgrest.ts`:\n * point postgrest-js at a dummy URL, intercept fetch, rewrite.\n *\n * Auth:\n * On every request the fetch wrapper reads the current access token\n * from the TokenManager (or falls back to the SDK's configured\n * `anonKey`) and forwards it as `Authorization: Bearer <jwt>`. The\n * MITWAY-BaaS backend's api-key middleware accepts it, the proxy\n * forwards it to PostgREST, and PostgREST verifies it with the shared\n * tenant JWT_SECRET and enforces RLS policies based on the role claim.\n */\n\nimport { PostgrestClient } from '@supabase/postgrest-js';\nimport { HttpClient } from '../lib/http-client';\nimport { TokenManager } from '../lib/token-manager';\nimport { MitwayBaasError } from '../types';\n\n/**\n * Custom fetch that:\n * 1. Rewrites the URL from postgrest-js's dummy format (`http://dummy/posts`)\n * to the MITWAY-BaaS backend proxy path\n * (`{baseUrl}/api/database/records/posts` or\n * `{baseUrl}/api/database/rpc/{fn}`).\n * 2. Injects the current access token (or anon key fallback) as the\n * `Authorization: Bearer <jwt>` header if one isn't already set.\n */\nfunction createMitwayBaasFetch(\n httpClient: HttpClient,\n tokenManager: TokenManager,\n anonKey: string | undefined,\n): typeof fetch {\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const url = typeof input === 'string' ? input : input.toString();\n const urlObj = new URL(url);\n\n // postgrest-js sends: http://dummy/tablename?params for tables\n // http://dummy/rpc/fnname?params for stored fns\n // Rewrite pathname to the backend proxy path. Strip the leading `/`\n // to make the join unambiguous.\n const pathname = urlObj.pathname.startsWith('/') ? urlObj.pathname.slice(1) : urlObj.pathname;\n const rpcMatch = pathname.match(/^rpc\\/(.+)$/);\n const endpoint = rpcMatch\n ? `/api/database/rpc/${rpcMatch[1]}`\n : `/api/database/records/${pathname}`;\n\n const targetUrl = `${httpClient.baseUrl}${endpoint}${urlObj.search}`;\n\n // Inject auth. Prefer the current user token, fall back to anonKey.\n // Don't overwrite Authorization if the caller already set one.\n const headers = new Headers(init?.headers);\n if (!headers.has('Authorization')) {\n const token = tokenManager.getAccessToken() ?? anonKey;\n if (token) {\n headers.set('Authorization', `Bearer ${token}`);\n }\n }\n\n return fetch(targetUrl, { ...init, headers });\n };\n}\n\nexport class Database {\n private postgrest: PostgrestClient<any, any, any>;\n private httpClient: HttpClient;\n\n constructor(\n httpClient: HttpClient,\n tokenManager: TokenManager,\n anonKey: string | undefined,\n ) {\n this.httpClient = httpClient;\n // The URL we pass to PostgrestClient is a dummy — the fetch wrapper\n // above rewrites every outgoing URL before it reaches the network.\n // Keeping it as `http://dummy` makes it obvious in stack traces that\n // nothing should ever actually dial this address.\n this.postgrest = new PostgrestClient<any, any, any>('http://dummy', {\n fetch: createMitwayBaasFetch(httpClient, tokenManager, anonKey),\n headers: {},\n });\n }\n\n /**\n * Build a PostgREST query against a table.\n *\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 * @example\n * const { data, error } = await client.database\n * .from('posts')\n * .insert({ title: 'Hello', content: 'World' })\n * .select()\n * .single();\n */\n from(table: string) {\n if (!table || typeof table !== 'string') {\n throw new MitwayBaasError(\n 'Database.from(table) requires a non-empty string',\n 400,\n 'INVALID_TABLE_NAME',\n );\n }\n return this.postgrest.from(table);\n }\n\n /**\n * Call a PostgreSQL stored function (RPC).\n *\n * @example\n * const { data, error } = await client.database\n * .rpc('get_user_stats', { user_id: 123 });\n */\n rpc(\n fn: string,\n args?: Record<string, unknown>,\n options?: { head?: boolean; get?: boolean; count?: 'exact' | 'planned' | 'estimated' },\n ) {\n return this.postgrest.rpc(fn, args, options);\n }\n\n /**\n * The backend base URL the database client is targeting. Useful for\n * debugging — the actual PostgREST instance is internal and not\n * reachable by the SDK directly.\n */\n getUrl(): string {\n return this.httpClient.baseUrl;\n }\n}\n","import { MitwayBaasConfig } from './types';\nimport { HttpClient } from './lib/http-client';\nimport { Logger } from './lib/logger';\nimport { TokenManager } from './lib/token-manager';\nimport { Auth } from './modules/auth';\nimport { Database } from './modules/database';\n\n/**\n * MITWAY-BaaS SDK client.\n *\n * @example\n * ```typescript\n * import { createClient } from '@mitway/sdk';\n *\n * const client = createClient({\n * baseUrl: 'https://acme.api.dev.nttmitway.com',\n * anonKey: 'eyJhbGciOiJIUzI1NiIs...', // optional\n * });\n *\n * // Auth\n * const { data: session, error } = await client.auth.signInWithPassword({\n * email: 'a@b.com',\n * password: 'pw',\n * });\n *\n * // Database — transparently routed through the backend proxy at\n * // /api/database/records/* (no separate PostgREST URL).\n * const { data, error: dbError } = await client.database\n * .from('posts')\n * .select('*')\n * .eq('user_id', session.user.id)\n * .order('created_at', { ascending: false });\n * ```\n */\nexport class MitwayBaasClient {\n private http: HttpClient;\n private tokenManager: TokenManager;\n public readonly auth: Auth;\n public readonly database: Database;\n\n constructor(config: MitwayBaasConfig = {}) {\n const logger = new Logger(config.debug);\n this.tokenManager = new TokenManager();\n this.http = new HttpClient(config, this.tokenManager, logger);\n this.auth = new Auth(this.http, this.tokenManager);\n this.database = new Database(this.http, this.tokenManager, config.anonKey);\n }\n\n /**\n * Escape hatch for callers that need to make custom requests against the\n * backend without going through `auth` or `database`.\n */\n getHttpClient(): HttpClient {\n return this.http;\n }\n}\n"],"mappings":"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","names":["timer"]}
package/dist/index.d.cts CHANGED
@@ -37,17 +37,15 @@ interface User {
37
37
 
38
38
  interface MitwayBaasConfig {
39
39
  /**
40
- * Base URL of the MITWAY-BaaS backend (auth, metadata, etc).
40
+ * Base URL of the MITWAY-BaaS backend. In production this is typically
41
+ * `https://{cliente}.api.dev.nttmitway.com` (or the equivalent pro
42
+ * domain). The SDK routes all traffic — auth, database (via the
43
+ * backend's PostgREST proxy at `/api/database/records/*`), and future
44
+ * storage/functions — through this one URL.
45
+ *
41
46
  * @default "http://localhost:7130"
42
47
  */
43
48
  baseUrl?: string;
44
- /**
45
- * Base URL of the per-cliente PostgREST instance. Used by the database
46
- * module. If omitted, calling `client.database.from(...)` will throw at
47
- * call time. The PostgREST URL is separate from `baseUrl` because the two
48
- * services are deployed as independent Pods in the per-cliente namespace.
49
- */
50
- postgrestUrl?: string;
51
49
  /**
52
50
  * Anonymous JWT (signed by the tenant's JWT_SECRET, role = "anon").
53
51
  * Used as a fallback Bearer token for unauthenticated requests when no
@@ -316,9 +314,8 @@ declare class Auth {
316
314
 
317
315
  declare class Database {
318
316
  private postgrest;
319
- private postgrestUrl;
320
- constructor(tokenManager: TokenManager, postgrestUrl: string | undefined, anonKey: string | undefined);
321
- private requireClient;
317
+ private httpClient;
318
+ constructor(httpClient: HttpClient, tokenManager: TokenManager, anonKey: string | undefined);
322
319
  /**
323
320
  * Build a PostgREST query against a table.
324
321
  *
@@ -351,10 +348,11 @@ declare class Database {
351
348
  count?: 'exact' | 'planned' | 'estimated';
352
349
  }): _supabase_postgrest_js.PostgrestFilterBuilder<any, any, any, any, string, null, "RPC">;
353
350
  /**
354
- * The PostgREST URL the database client is talking to, or undefined if
355
- * the database module is not configured.
351
+ * The backend base URL the database client is targeting. Useful for
352
+ * debugging — the actual PostgREST instance is internal and not
353
+ * reachable by the SDK directly.
356
354
  */
357
- getUrl(): string | undefined;
355
+ getUrl(): string;
358
356
  }
359
357
 
360
358
  /**
@@ -362,12 +360,11 @@ declare class Database {
362
360
  *
363
361
  * @example
364
362
  * ```typescript
365
- * import { createClient } from '@mitway-baas/sdk';
363
+ * import { createClient } from '@mitway/sdk';
366
364
  *
367
365
  * const client = createClient({
368
- * baseUrl: 'https://acme.api.dev.nttmitway.com', // backend (auth)
369
- * postgrestUrl: 'https://acme.db.dev.nttmitway.com', // postgrest (db)
370
- * anonKey: 'eyJhbGciOiJIUzI1NiIs...', // optional
366
+ * baseUrl: 'https://acme.api.dev.nttmitway.com',
367
+ * anonKey: 'eyJhbGciOiJIUzI1NiIs...', // optional
371
368
  * });
372
369
  *
373
370
  * // Auth
@@ -376,7 +373,8 @@ declare class Database {
376
373
  * password: 'pw',
377
374
  * });
378
375
  *
379
- * // Database
376
+ * // Database — transparently routed through the backend proxy at
377
+ * // /api/database/records/* (no separate PostgREST URL).
380
378
  * const { data, error: dbError } = await client.database
381
379
  * .from('posts')
382
380
  * .select('*')
package/dist/index.d.ts CHANGED
@@ -37,17 +37,15 @@ interface User {
37
37
 
38
38
  interface MitwayBaasConfig {
39
39
  /**
40
- * Base URL of the MITWAY-BaaS backend (auth, metadata, etc).
40
+ * Base URL of the MITWAY-BaaS backend. In production this is typically
41
+ * `https://{cliente}.api.dev.nttmitway.com` (or the equivalent pro
42
+ * domain). The SDK routes all traffic — auth, database (via the
43
+ * backend's PostgREST proxy at `/api/database/records/*`), and future
44
+ * storage/functions — through this one URL.
45
+ *
41
46
  * @default "http://localhost:7130"
42
47
  */
43
48
  baseUrl?: string;
44
- /**
45
- * Base URL of the per-cliente PostgREST instance. Used by the database
46
- * module. If omitted, calling `client.database.from(...)` will throw at
47
- * call time. The PostgREST URL is separate from `baseUrl` because the two
48
- * services are deployed as independent Pods in the per-cliente namespace.
49
- */
50
- postgrestUrl?: string;
51
49
  /**
52
50
  * Anonymous JWT (signed by the tenant's JWT_SECRET, role = "anon").
53
51
  * Used as a fallback Bearer token for unauthenticated requests when no
@@ -316,9 +314,8 @@ declare class Auth {
316
314
 
317
315
  declare class Database {
318
316
  private postgrest;
319
- private postgrestUrl;
320
- constructor(tokenManager: TokenManager, postgrestUrl: string | undefined, anonKey: string | undefined);
321
- private requireClient;
317
+ private httpClient;
318
+ constructor(httpClient: HttpClient, tokenManager: TokenManager, anonKey: string | undefined);
322
319
  /**
323
320
  * Build a PostgREST query against a table.
324
321
  *
@@ -351,10 +348,11 @@ declare class Database {
351
348
  count?: 'exact' | 'planned' | 'estimated';
352
349
  }): _supabase_postgrest_js.PostgrestFilterBuilder<any, any, any, any, string, null, "RPC">;
353
350
  /**
354
- * The PostgREST URL the database client is talking to, or undefined if
355
- * the database module is not configured.
351
+ * The backend base URL the database client is targeting. Useful for
352
+ * debugging — the actual PostgREST instance is internal and not
353
+ * reachable by the SDK directly.
356
354
  */
357
- getUrl(): string | undefined;
355
+ getUrl(): string;
358
356
  }
359
357
 
360
358
  /**
@@ -362,12 +360,11 @@ declare class Database {
362
360
  *
363
361
  * @example
364
362
  * ```typescript
365
- * import { createClient } from '@mitway-baas/sdk';
363
+ * import { createClient } from '@mitway/sdk';
366
364
  *
367
365
  * const client = createClient({
368
- * baseUrl: 'https://acme.api.dev.nttmitway.com', // backend (auth)
369
- * postgrestUrl: 'https://acme.db.dev.nttmitway.com', // postgrest (db)
370
- * anonKey: 'eyJhbGciOiJIUzI1NiIs...', // optional
366
+ * baseUrl: 'https://acme.api.dev.nttmitway.com',
367
+ * anonKey: 'eyJhbGciOiJIUzI1NiIs...', // optional
371
368
  * });
372
369
  *
373
370
  * // Auth
@@ -376,7 +373,8 @@ declare class Database {
376
373
  * password: 'pw',
377
374
  * });
378
375
  *
379
- * // Database
376
+ * // Database — transparently routed through the backend proxy at
377
+ * // /api/database/records/* (no separate PostgREST URL).
380
378
  * const { data, error: dbError } = await client.database
381
379
  * .from('posts')
382
380
  * .select('*')
package/dist/index.js CHANGED
@@ -702,8 +702,14 @@ var Auth = class {
702
702
 
703
703
  // src/modules/database.ts
704
704
  import { PostgrestClient } from "@supabase/postgrest-js";
705
- function createAuthedFetch(tokenManager, anonKey) {
705
+ function createMitwayBaasFetch(httpClient, tokenManager, anonKey) {
706
706
  return async (input, init) => {
707
+ const url = typeof input === "string" ? input : input.toString();
708
+ const urlObj = new URL(url);
709
+ const pathname = urlObj.pathname.startsWith("/") ? urlObj.pathname.slice(1) : urlObj.pathname;
710
+ const rpcMatch = pathname.match(/^rpc\/(.+)$/);
711
+ const endpoint = rpcMatch ? `/api/database/rpc/${rpcMatch[1]}` : `/api/database/records/${pathname}`;
712
+ const targetUrl = `${httpClient.baseUrl}${endpoint}${urlObj.search}`;
707
713
  const headers = new Headers(init?.headers);
708
714
  if (!headers.has("Authorization")) {
709
715
  const token = tokenManager.getAccessToken() ?? anonKey;
@@ -711,32 +717,18 @@ function createAuthedFetch(tokenManager, anonKey) {
711
717
  headers.set("Authorization", `Bearer ${token}`);
712
718
  }
713
719
  }
714
- return fetch(input, { ...init, headers });
720
+ return fetch(targetUrl, { ...init, headers });
715
721
  };
716
722
  }
717
723
  var Database = class {
718
724
  postgrest;
719
- postgrestUrl;
720
- constructor(tokenManager, postgrestUrl, anonKey) {
721
- this.postgrestUrl = postgrestUrl;
722
- if (postgrestUrl) {
723
- this.postgrest = new PostgrestClient(postgrestUrl, {
724
- fetch: createAuthedFetch(tokenManager, anonKey),
725
- headers: {}
726
- });
727
- } else {
728
- this.postgrest = null;
729
- }
730
- }
731
- requireClient() {
732
- if (!this.postgrest) {
733
- throw new MitwayBaasError(
734
- "Database is not configured. Pass `postgrestUrl` in the SDK config to enable database operations.",
735
- 500,
736
- "DATABASE_NOT_CONFIGURED"
737
- );
738
- }
739
- return this.postgrest;
725
+ httpClient;
726
+ constructor(httpClient, tokenManager, anonKey) {
727
+ this.httpClient = httpClient;
728
+ this.postgrest = new PostgrestClient("http://dummy", {
729
+ fetch: createMitwayBaasFetch(httpClient, tokenManager, anonKey),
730
+ headers: {}
731
+ });
740
732
  }
741
733
  /**
742
734
  * Build a PostgREST query against a table.
@@ -757,7 +749,14 @@ var Database = class {
757
749
  * .single();
758
750
  */
759
751
  from(table) {
760
- return this.requireClient().from(table);
752
+ if (!table || typeof table !== "string") {
753
+ throw new MitwayBaasError(
754
+ "Database.from(table) requires a non-empty string",
755
+ 400,
756
+ "INVALID_TABLE_NAME"
757
+ );
758
+ }
759
+ return this.postgrest.from(table);
761
760
  }
762
761
  /**
763
762
  * Call a PostgreSQL stored function (RPC).
@@ -767,14 +766,15 @@ var Database = class {
767
766
  * .rpc('get_user_stats', { user_id: 123 });
768
767
  */
769
768
  rpc(fn, args, options) {
770
- return this.requireClient().rpc(fn, args, options);
769
+ return this.postgrest.rpc(fn, args, options);
771
770
  }
772
771
  /**
773
- * The PostgREST URL the database client is talking to, or undefined if
774
- * the database module is not configured.
772
+ * The backend base URL the database client is targeting. Useful for
773
+ * debugging — the actual PostgREST instance is internal and not
774
+ * reachable by the SDK directly.
775
775
  */
776
776
  getUrl() {
777
- return this.postgrestUrl;
777
+ return this.httpClient.baseUrl;
778
778
  }
779
779
  };
780
780
 
@@ -789,7 +789,7 @@ var MitwayBaasClient = class {
789
789
  this.tokenManager = new TokenManager();
790
790
  this.http = new HttpClient(config, this.tokenManager, logger);
791
791
  this.auth = new Auth(this.http, this.tokenManager);
792
- this.database = new Database(this.tokenManager, config.postgrestUrl, config.anonKey);
792
+ this.database = new Database(this.http, this.tokenManager, config.anonKey);
793
793
  }
794
794
  /**
795
795
  * Escape hatch for callers that need to make custom requests against the
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/lib/logger.ts","../src/lib/token-manager.ts","../src/lib/http-client.ts","../src/modules/auth.ts","../src/modules/database.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["/**\n * MITWAY-BaaS SDK types — only SDK-specific shapes live here.\n * The `User` shape is inlined in `./lib/user` so this package has zero\n * MITWAY-BaaS workspace dependencies.\n */\n\nimport type { User } from './lib/user';\n\nexport interface MitwayBaasConfig {\n /**\n * Base URL of the MITWAY-BaaS backend (auth, metadata, etc).\n * @default \"http://localhost:7130\"\n */\n baseUrl?: string;\n\n /**\n * Base URL of the per-cliente PostgREST instance. Used by the database\n * module. If omitted, calling `client.database.from(...)` will throw at\n * call time. The PostgREST URL is separate from `baseUrl` because the two\n * services are deployed as independent Pods in the per-cliente namespace.\n */\n postgrestUrl?: string;\n\n /**\n * Anonymous JWT (signed by the tenant's JWT_SECRET, role = \"anon\").\n * Used as a fallback Bearer token for unauthenticated requests when no\n * user session is active.\n */\n anonKey?: string;\n\n /**\n * Custom fetch implementation. Useful in Node < 18 or test environments.\n * Defaults to `globalThis.fetch`.\n */\n fetch?: typeof fetch;\n\n /**\n * Custom default headers included on every request.\n */\n headers?: Record<string, string>;\n\n /**\n * Enable debug logging. `true` logs to console; pass a function to receive\n * log lines instead.\n */\n debug?: boolean | ((message: string, ...args: any[]) => void);\n\n /**\n * Per-request timeout in milliseconds. 0 disables the timeout.\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Number of retry attempts on network errors and 5xx responses. Client\n * errors (4xx) are never retried. 0 disables retries.\n * @default 3\n */\n retryCount?: number;\n\n /**\n * Initial delay before the first retry, in ms. Doubles each attempt with\n * ±15% jitter.\n * @default 500\n */\n retryDelay?: number;\n\n /**\n * Automatically refresh the access token on 401 INVALID_TOKEN responses\n * and retry the original request.\n * @default true\n */\n autoRefreshToken?: boolean;\n}\n\n/**\n * Active user session in memory. Mirrors what the auth endpoints return.\n */\nexport interface AuthSession {\n user: User;\n accessToken: string;\n expiresAt?: Date;\n}\n\n/**\n * Minimal payload that auth refresh endpoints emit. The SDK uses this to\n * refresh the in-memory session.\n */\nexport interface AuthRefreshResponse {\n user: User;\n accessToken: string;\n refreshToken?: string;\n csrfToken?: string;\n}\n\n/**\n * The `{ data, error }` envelope used by the MITWAY-BaaS backend on every\n * response. The SDK unwraps `data` for happy-path returns and converts\n * `error` into a `MitwayBaasError`.\n */\nexport interface ApiError {\n error: string;\n message: string;\n statusCode: number;\n nextActions?: string;\n}\n\nexport class MitwayBaasError extends Error {\n public statusCode: number;\n public error: string;\n public nextActions?: string;\n\n constructor(\n message: string,\n statusCode: number,\n error: string,\n nextActions?: string,\n ) {\n super(message);\n this.name = 'MitwayBaasError';\n this.statusCode = statusCode;\n this.error = error;\n this.nextActions = nextActions;\n }\n\n static fromApiError(apiError: ApiError): MitwayBaasError {\n return new MitwayBaasError(\n apiError.message,\n apiError.statusCode,\n apiError.error,\n apiError.nextActions,\n );\n }\n}\n","/**\n * Debug logger for the MITWAY-BaaS SDK.\n *\n * Logs HTTP request/response details with automatic redaction of sensitive\n * headers and body fields. Disabled by default; pass `debug: true` (or a\n * custom log function) on the SDK config to enable.\n */\n\ntype LogFunction = (message: string, ...args: any[]) => void;\n\nconst SENSITIVE_HEADERS = ['authorization', 'x-api-key', 'cookie', 'set-cookie'];\n\nconst SENSITIVE_BODY_KEYS = [\n 'password', 'token', 'accesstoken', 'refreshtoken',\n 'authorization', 'secret', 'apikey', 'api_key',\n 'email', 'ssn', 'creditcard', 'credit_card',\n];\n\nfunction redactHeaders(headers: Record<string, string>): Record<string, string> {\n const redacted: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (SENSITIVE_HEADERS.includes(key.toLowerCase())) {\n redacted[key] = '***REDACTED***';\n } else {\n redacted[key] = value;\n }\n }\n return redacted;\n}\n\nfunction sanitizeBody(body: any): any {\n if (body === null || body === undefined) return body;\n if (typeof body === 'string') {\n try {\n const parsed = JSON.parse(body);\n return sanitizeBody(parsed);\n } catch {\n return body;\n }\n }\n if (Array.isArray(body)) return body.map(sanitizeBody);\n if (typeof body === 'object') {\n const sanitized: Record<string, any> = {};\n for (const [key, value] of Object.entries(body)) {\n if (SENSITIVE_BODY_KEYS.includes(key.toLowerCase().replace(/[-_]/g, ''))) {\n sanitized[key] = '***REDACTED***';\n } else {\n sanitized[key] = sanitizeBody(value);\n }\n }\n return sanitized;\n }\n return body;\n}\n\nfunction formatBody(body: any): string {\n if (body === undefined || body === null) return '';\n if (typeof body === 'string') {\n try {\n return JSON.stringify(JSON.parse(body), null, 2);\n } catch {\n return body;\n }\n }\n if (typeof FormData !== 'undefined' && body instanceof FormData) {\n return '[FormData]';\n }\n try {\n return JSON.stringify(body, null, 2);\n } catch {\n return '[Unserializable body]';\n }\n}\n\nexport class Logger {\n public enabled: boolean;\n private customLog: LogFunction | null;\n\n constructor(debug?: boolean | LogFunction) {\n if (typeof debug === 'function') {\n this.enabled = true;\n this.customLog = debug;\n } else {\n this.enabled = !!debug;\n this.customLog = null;\n }\n }\n\n log(message: string, ...args: any[]): void {\n if (!this.enabled) return;\n const formatted = `[MITWAY-BaaS Debug] ${message}`;\n if (this.customLog) {\n this.customLog(formatted, ...args);\n } else {\n console.log(formatted, ...args);\n }\n }\n\n warn(message: string, ...args: any[]): void {\n if (!this.enabled) return;\n const formatted = `[MITWAY-BaaS Debug] ${message}`;\n if (this.customLog) {\n this.customLog(formatted, ...args);\n } else {\n console.warn(formatted, ...args);\n }\n }\n\n error(message: string, ...args: any[]): void {\n if (!this.enabled) return;\n const formatted = `[MITWAY-BaaS Debug] ${message}`;\n if (this.customLog) {\n this.customLog(formatted, ...args);\n } else {\n console.error(formatted, ...args);\n }\n }\n\n logRequest(\n method: string,\n url: string,\n headers?: Record<string, string>,\n body?: any\n ): void {\n if (!this.enabled) return;\n const parts: string[] = [`→ ${method} ${url}`];\n if (headers && Object.keys(headers).length > 0) {\n parts.push(` Headers: ${JSON.stringify(redactHeaders(headers))}`);\n }\n const formattedBody = formatBody(sanitizeBody(body));\n if (formattedBody) {\n const truncated = formattedBody.length > 1000\n ? formattedBody.slice(0, 1000) + '... [truncated]'\n : formattedBody;\n parts.push(` Body: ${truncated}`);\n }\n this.log(parts.join('\\n'));\n }\n\n logResponse(\n method: string,\n url: string,\n status: number,\n durationMs: number,\n body?: any\n ): void {\n if (!this.enabled) return;\n const parts: string[] = [\n `← ${method} ${url} ${status} (${durationMs}ms)`,\n ];\n const formattedBody = formatBody(sanitizeBody(body));\n if (formattedBody) {\n const truncated = formattedBody.length > 1000\n ? formattedBody.slice(0, 1000) + '... [truncated]'\n : formattedBody;\n parts.push(` Body: ${truncated}`);\n }\n if (status >= 400) {\n this.error(parts.join('\\n'));\n } else {\n this.log(parts.join('\\n'));\n }\n }\n}\n","/**\n * Token Manager for the MITWAY-BaaS SDK.\n *\n * In-memory storage for the access token + user. Browser CSRF token lives\n * in a cookie so the cookie-based refresh flow works across page reloads.\n */\n\nimport type { User } from './user';\nimport type { AuthSession } from '../types';\n\nexport const CSRF_TOKEN_COOKIE = 'mitway_baas_csrf_token';\n\nexport function getCsrfToken(): string | null {\n if (typeof document === 'undefined') return null;\n const match = document.cookie\n .split(';')\n .find((c) => c.trim().startsWith(`${CSRF_TOKEN_COOKIE}=`));\n if (!match) return null;\n return match.split('=')[1] || null;\n}\n\nexport function setCsrfToken(token: string): void {\n if (typeof document === 'undefined') return;\n const maxAge = 7 * 24 * 60 * 60; // 7 days\n const secure =\n typeof window !== 'undefined' && window.location.protocol === 'https:'\n ? '; Secure'\n : '';\n document.cookie = `${CSRF_TOKEN_COOKIE}=${encodeURIComponent(token)}; path=/; max-age=${maxAge}; SameSite=Lax${secure}`;\n}\n\nexport function clearCsrfToken(): void {\n if (typeof document === 'undefined') return;\n const secure =\n typeof window !== 'undefined' && window.location.protocol === 'https:'\n ? '; Secure'\n : '';\n document.cookie = `${CSRF_TOKEN_COOKIE}=; path=/; max-age=0; SameSite=Lax${secure}`;\n}\n\nexport class TokenManager {\n private accessToken: string | null = null;\n private user: User | null = null;\n\n /** Fired when the access token changes (used by long-lived consumers). */\n onTokenChange: (() => void) | null = null;\n\n saveSession(session: AuthSession): void {\n const tokenChanged = session.accessToken !== this.accessToken;\n this.accessToken = session.accessToken;\n this.user = session.user;\n if (tokenChanged && this.onTokenChange) {\n this.onTokenChange();\n }\n }\n\n getSession(): AuthSession | null {\n if (!this.accessToken || !this.user) return null;\n return {\n accessToken: this.accessToken,\n user: this.user,\n };\n }\n\n getAccessToken(): string | null {\n return this.accessToken;\n }\n\n setAccessToken(token: string): void {\n const tokenChanged = token !== this.accessToken;\n this.accessToken = token;\n if (tokenChanged && this.onTokenChange) {\n this.onTokenChange();\n }\n }\n\n getUser(): User | null {\n return this.user;\n }\n\n setUser(user: User): void {\n this.user = user;\n }\n\n clearSession(): void {\n const hadToken = this.accessToken !== null;\n this.accessToken = null;\n this.user = null;\n if (hadToken && this.onTokenChange) {\n this.onTokenChange();\n }\n }\n}\n","/**\n * HttpClient with retry, timeout, abort signal composition, and automatic\n * token refresh on 401 INVALID_TOKEN responses.\n *\n * Ported from the InsForge SDK with rebranding plus one route change:\n * the refresh endpoint is `/api/auth/refresh` (MITWAY-BaaS) instead of\n * `/api/auth/sessions/current` (InsForge).\n */\n\nimport {\n MitwayBaasConfig,\n ApiError,\n MitwayBaasError,\n AuthRefreshResponse,\n} from '../types';\nimport { Logger } from './logger';\nimport {\n clearCsrfToken,\n getCsrfToken,\n setCsrfToken,\n TokenManager,\n} from './token-manager';\n\ntype JsonRequestBody = Record<string, unknown> | unknown[] | null;\n\nexport interface RequestOptions extends Omit<RequestInit, 'body'> {\n params?: Record<string, string>;\n body?: RequestInit['body'] | JsonRequestBody;\n /**\n * Allow retrying non-idempotent requests (POST, PATCH). Off by default to\n * prevent duplicate writes on transient server errors.\n */\n idempotent?: boolean;\n}\n\nconst RETRYABLE_STATUS_CODES = new Set([500, 502, 503, 504]);\nconst IDEMPOTENT_METHODS = new Set(['GET', 'HEAD', 'PUT', 'DELETE', 'OPTIONS']);\n\nexport class HttpClient {\n public readonly baseUrl: string;\n public readonly fetch: typeof fetch;\n private defaultHeaders: Record<string, string>;\n private anonKey: string | undefined;\n private userToken: string | null = null;\n private logger: Logger;\n private autoRefreshToken: boolean = true;\n private isRefreshing: boolean = false;\n private refreshPromise: Promise<AuthRefreshResponse> | null = null;\n private tokenManager: TokenManager;\n private refreshToken: string | null = null;\n private timeout: number;\n private retryCount: number;\n private retryDelay: number;\n\n constructor(\n config: MitwayBaasConfig,\n tokenManager?: TokenManager,\n logger?: Logger,\n ) {\n this.baseUrl = config.baseUrl || 'http://localhost:7130';\n this.autoRefreshToken = config.autoRefreshToken ?? true;\n this.fetch =\n config.fetch ||\n (globalThis.fetch\n ? globalThis.fetch.bind(globalThis)\n : (undefined as any));\n this.anonKey = config.anonKey;\n this.defaultHeaders = {\n ...config.headers,\n };\n this.tokenManager = tokenManager ?? new TokenManager();\n this.logger = logger || new Logger(false);\n this.timeout = config.timeout ?? 30_000;\n this.retryCount = config.retryCount ?? 3;\n this.retryDelay = config.retryDelay ?? 500;\n\n if (!this.fetch) {\n throw new Error(\n 'Fetch is not available. Provide a fetch implementation in the SDK 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 if (key === 'select') {\n // Normalize PostgREST select syntax (whitespace inside relationships).\n let normalizedValue = value.replace(/\\s+/g, ' ').trim();\n normalizedValue = normalizedValue\n .replace(/\\s*\\(\\s*/g, '(')\n .replace(/\\s*\\)\\s*/g, ')')\n .replace(/\\(\\s+/g, '(')\n .replace(/\\s+\\)/g, ')')\n .replace(/,\\s+(?=[^()]*\\))/g, ',');\n url.searchParams.append(key, normalizedValue);\n } else {\n url.searchParams.append(key, value);\n }\n });\n }\n return url.toString();\n }\n\n private isRetryableStatus(status: number): boolean {\n return RETRYABLE_STATUS_CODES.has(status);\n }\n\n private computeRetryDelay(attempt: number): number {\n const base = this.retryDelay * Math.pow(2, attempt - 1);\n const jitter = base * (0.85 + Math.random() * 0.3);\n return Math.round(jitter);\n }\n\n private async handleRequest<T>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n const {\n params,\n headers = {},\n body,\n signal: callerSignal,\n ...fetchOptions\n } = options as RequestOptions & { signal?: AbortSignal };\n\n const url = this.buildUrl(path, params);\n const startTime = Date.now();\n const canRetry =\n IDEMPOTENT_METHODS.has(method.toUpperCase()) ||\n options.idempotent === true;\n const maxAttempts = canRetry ? this.retryCount : 0;\n\n const requestHeaders: Record<string, string> = {\n ...this.defaultHeaders,\n };\n\n const authToken = this.userToken || this.anonKey;\n if (authToken) {\n requestHeaders['Authorization'] = `Bearer ${authToken}`;\n }\n\n let processedBody: any;\n if (body !== undefined) {\n if (typeof FormData !== 'undefined' && body instanceof FormData) {\n processedBody = body;\n } else {\n if (method !== 'GET') {\n requestHeaders['Content-Type'] = 'application/json;charset=UTF-8';\n }\n processedBody = JSON.stringify(body);\n }\n }\n\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n requestHeaders[key] = value;\n });\n } else if (Array.isArray(headers)) {\n headers.forEach(([key, value]) => {\n requestHeaders[key] = value;\n });\n } else {\n Object.assign(requestHeaders, headers);\n }\n\n this.logger.logRequest(method, url, requestHeaders, processedBody);\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxAttempts; attempt++) {\n if (attempt > 0) {\n const delay = this.computeRetryDelay(attempt);\n this.logger.warn(\n `Retry ${attempt}/${maxAttempts} for ${method} ${url} in ${delay}ms`,\n );\n if (callerSignal?.aborted) throw callerSignal.reason;\n await new Promise<void>((resolve, reject) => {\n const onAbort = () => {\n clearTimeout(timer);\n reject(callerSignal!.reason);\n };\n const timer = setTimeout(() => {\n if (callerSignal)\n callerSignal.removeEventListener('abort', onAbort);\n resolve();\n }, delay);\n if (callerSignal) {\n callerSignal.addEventListener('abort', onAbort, { once: true });\n }\n });\n }\n\n let controller: AbortController | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n if (this.timeout > 0 || callerSignal) {\n controller = new AbortController();\n\n if (this.timeout > 0) {\n timer = setTimeout(() => controller!.abort(), this.timeout);\n }\n\n if (callerSignal) {\n if (callerSignal.aborted) {\n controller.abort(callerSignal.reason);\n } else {\n const onCallerAbort = () => controller!.abort(callerSignal!.reason);\n callerSignal.addEventListener('abort', onCallerAbort, { once: true });\n controller.signal.addEventListener(\n 'abort',\n () => {\n callerSignal!.removeEventListener('abort', onCallerAbort);\n },\n { once: true },\n );\n }\n }\n }\n\n try {\n const response = await this.fetch(url, {\n method,\n headers: requestHeaders,\n body: processedBody,\n ...fetchOptions,\n ...(controller ? { signal: controller.signal } : {}),\n });\n\n if (this.isRetryableStatus(response.status) && attempt < maxAttempts) {\n if (timer !== undefined) clearTimeout(timer);\n await response.body?.cancel();\n lastError = new MitwayBaasError(\n `Server error: ${response.status} ${response.statusText}`,\n response.status,\n 'SERVER_ERROR',\n );\n continue;\n }\n\n if (response.status === 204) {\n if (timer !== undefined) clearTimeout(timer);\n return undefined as T;\n }\n\n let data: any;\n const contentType = response.headers.get('content-type');\n try {\n if (contentType?.includes('json')) {\n data = await response.json();\n } else {\n data = await response.text();\n }\n } catch (parseErr: any) {\n if (timer !== undefined) clearTimeout(timer);\n throw new MitwayBaasError(\n `Failed to parse response body: ${parseErr?.message || 'Unknown error'}`,\n response.status,\n response.ok ? 'PARSE_ERROR' : 'REQUEST_FAILED',\n );\n }\n\n if (timer !== undefined) clearTimeout(timer);\n\n if (!response.ok) {\n this.logger.logResponse(\n method,\n url,\n response.status,\n Date.now() - startTime,\n data,\n );\n if (data && typeof data === 'object' && 'error' in data) {\n if (!data.statusCode && !data.status) {\n data.statusCode = response.status;\n }\n const error = MitwayBaasError.fromApiError(data as ApiError);\n Object.keys(data).forEach((key) => {\n if (key !== 'error' && key !== 'message' && key !== 'statusCode') {\n (error as any)[key] = data[key];\n }\n });\n throw error;\n }\n throw new MitwayBaasError(\n `Request failed: ${response.statusText}`,\n response.status,\n 'REQUEST_FAILED',\n );\n }\n\n this.logger.logResponse(\n method,\n url,\n response.status,\n Date.now() - startTime,\n data,\n );\n return data as T;\n } catch (err: any) {\n if (timer !== undefined) clearTimeout(timer);\n\n if (err?.name === 'AbortError') {\n if (\n controller &&\n controller.signal.aborted &&\n this.timeout > 0 &&\n !callerSignal?.aborted\n ) {\n throw new MitwayBaasError(\n `Request timed out after ${this.timeout}ms`,\n 408,\n 'REQUEST_TIMEOUT',\n );\n }\n throw err;\n }\n\n if (err instanceof MitwayBaasError) {\n throw err;\n }\n\n if (attempt < maxAttempts) {\n lastError = err;\n continue;\n }\n\n throw new MitwayBaasError(\n `Network request failed: ${err?.message || 'Unknown error'}`,\n 0,\n 'NETWORK_ERROR',\n );\n }\n }\n\n throw (\n lastError ||\n new MitwayBaasError(\n 'Request failed after all retry attempts',\n 0,\n 'NETWORK_ERROR',\n )\n );\n }\n\n async request<T>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n try {\n return await this.handleRequest<T>(method, path, { ...options });\n } catch (error) {\n if (\n error instanceof MitwayBaasError &&\n error.statusCode === 401 &&\n error.error === 'INVALID_TOKEN' &&\n this.autoRefreshToken\n ) {\n try {\n const newTokenData = await this.handleTokenRefresh();\n this.setAuthToken(newTokenData.accessToken);\n this.tokenManager!.saveSession(newTokenData);\n if (newTokenData.csrfToken) {\n setCsrfToken(newTokenData.csrfToken);\n }\n if (newTokenData.refreshToken) {\n this.setRefreshToken(newTokenData.refreshToken);\n }\n return await this.handleRequest<T>(method, path, { ...options });\n } catch (refreshError) {\n this.tokenManager.clearSession();\n this.userToken = null;\n this.refreshToken = null;\n clearCsrfToken();\n throw refreshError;\n }\n }\n throw error;\n }\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 this.userToken = token;\n }\n\n setRefreshToken(token: string | null) {\n this.refreshToken = token;\n }\n\n getHeaders(): Record<string, string> {\n const headers = { ...this.defaultHeaders };\n const authToken = this.userToken || this.anonKey;\n if (authToken) {\n headers['Authorization'] = `Bearer ${authToken}`;\n }\n return headers;\n }\n\n /**\n * Refresh the current session by calling the MITWAY-BaaS refresh endpoint.\n * Note: the route is `/api/auth/refresh` (POST), not the InsForge\n * `/api/auth/sessions/current` route. Returns the new access token + user.\n */\n async handleTokenRefresh(): Promise<AuthRefreshResponse> {\n if (this.isRefreshing) {\n return this.refreshPromise!;\n }\n\n this.isRefreshing = true;\n this.refreshPromise = (async () => {\n try {\n const csrfToken = getCsrfToken();\n const body = this.refreshToken\n ? { refreshToken: this.refreshToken }\n : undefined;\n const response = await this.handleRequest<AuthRefreshResponse>(\n 'POST',\n '/api/auth/refresh',\n {\n body,\n headers: csrfToken ? { 'X-CSRF-Token': csrfToken } : {},\n credentials: 'include',\n },\n );\n return response;\n } finally {\n this.isRefreshing = false;\n this.refreshPromise = null;\n }\n })();\n\n return this.refreshPromise;\n }\n}\n","/**\n * Auth module — MITWAY-BaaS specific.\n *\n * Targets the routes that the MITWAY-BaaS backend currently exposes:\n * POST /api/auth/register → signUp\n * POST /api/auth/login → signInWithPassword\n * POST /api/auth/logout → signOut\n * POST /api/auth/refresh → refreshSession (also auto-called by HttpClient)\n *\n * OAuth, email verification, password reset, and the InsForge-only\n * profile/sessions admin endpoints are NOT included — the backend does not\n * implement them yet. When it does, port the corresponding methods from the\n * upstream InsForge SDK (`InsForge/InsForge-sdk-js/src/modules/auth/auth.ts`).\n */\n\nimport type { User } from '../lib/user';\nimport { HttpClient } from '../lib/http-client';\nimport { TokenManager, setCsrfToken, clearCsrfToken } from '../lib/token-manager';\nimport { AuthSession, MitwayBaasError } from '../types';\n\nexport interface SignUpRequest {\n email: string;\n password: string;\n name?: string;\n}\n\nexport interface SignInRequest {\n email: string;\n password: string;\n}\n\n/**\n * The shape the backend returns from /register, /login, and /refresh. Mirrors\n * what the existing backend handlers send: `{ user, accessToken, refreshToken,\n * csrfToken? }` wrapped in the standard `{ data, error }` envelope. The SDK\n * unwraps the envelope before reaching this type, so consumers see the raw\n * shape.\n */\nexport interface AuthResponse {\n user: User;\n accessToken: string;\n refreshToken?: string;\n csrfToken?: string;\n}\n\nexport type AuthResult<T> = {\n data: T | null;\n error: MitwayBaasError | null;\n};\n\nfunction wrapError<T>(error: unknown, fallbackMessage: string): AuthResult<T> {\n if (error instanceof MitwayBaasError) {\n return { data: null, error };\n }\n return {\n data: null,\n error: new MitwayBaasError(\n error instanceof Error ? error.message : fallbackMessage,\n 500,\n 'AUTH_ERROR',\n ),\n };\n}\n\nexport class Auth {\n constructor(\n private http: HttpClient,\n private tokenManager: TokenManager,\n ) {}\n\n /**\n * Persist the session in memory + HttpClient defaults so subsequent\n * requests carry the new bearer token automatically.\n */\n private saveSessionFromResponse(response: AuthResponse): void {\n const session: AuthSession = {\n accessToken: response.accessToken,\n user: response.user,\n };\n if (response.csrfToken) {\n setCsrfToken(response.csrfToken);\n }\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(response.accessToken);\n this.http.setRefreshToken(response.refreshToken ?? null);\n }\n\n /**\n * Create a new user account and start a session.\n *\n * @example\n * const { data, error } = await client.auth.signUp({\n * email: 'a@b.com',\n * password: 'a-strong-password',\n * name: 'Alice'\n * });\n */\n async signUp(request: SignUpRequest): Promise<AuthResult<AuthResponse>> {\n try {\n const response = await this.http.post<AuthResponse>(\n '/api/auth/register',\n request,\n { credentials: 'include' },\n );\n if (response?.accessToken && response.user) {\n this.saveSessionFromResponse(response);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<AuthResponse>(error, 'Sign up failed');\n }\n }\n\n /**\n * Sign in with email + password and start a session.\n */\n async signInWithPassword(\n request: SignInRequest,\n ): Promise<AuthResult<AuthResponse>> {\n try {\n const response = await this.http.post<AuthResponse>(\n '/api/auth/login',\n request,\n { credentials: 'include' },\n );\n if (response?.accessToken && response.user) {\n this.saveSessionFromResponse(response);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<AuthResponse>(error, 'Sign in failed');\n }\n }\n\n /**\n * End the current session. Clears in-memory state even if the backend\n * call fails (network/offline).\n */\n async signOut(): Promise<{ error: MitwayBaasError | null }> {\n try {\n try {\n await this.http.post('/api/auth/logout', undefined, {\n credentials: 'include',\n });\n } catch {\n // Backend logout failure is non-fatal — local state still clears.\n }\n this.tokenManager.clearSession();\n this.http.setAuthToken(null);\n this.http.setRefreshToken(null);\n clearCsrfToken();\n return { error: null };\n } catch {\n return {\n error: new MitwayBaasError('Failed to sign out', 500, 'SIGNOUT_ERROR'),\n };\n }\n }\n\n /**\n * Manually refresh the current session. The HttpClient will call this\n * automatically on 401 INVALID_TOKEN responses; consumers usually do\n * not need to call it directly.\n */\n async refreshSession(): Promise<AuthResult<AuthResponse>> {\n try {\n const response = await this.http.handleTokenRefresh();\n if (response?.accessToken && response.user) {\n this.saveSessionFromResponse(response);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<AuthResponse>(error, 'Session refresh failed');\n }\n }\n\n /**\n * Get the current in-memory session, or null if the user is not signed in.\n * Synchronous — does not hit the network.\n */\n getSession(): AuthSession | null {\n return this.tokenManager.getSession();\n }\n\n /**\n * Get the current in-memory user, or null if not signed in.\n */\n getUser(): User | null {\n return this.tokenManager.getUser();\n }\n}\n","/**\n * Database module — wraps `@supabase/postgrest-js` and points it directly\n * at the per-cliente PostgREST instance.\n *\n * Why direct (not via the backend like InsForge does):\n * - InsForge's SDK proxies through `/api/database/records/{table}` on the\n * backend, which then forwards to PostgREST internally. MITWAY-BaaS does\n * not have that proxy route — PostgREST is its own Pod in the per-cliente\n * namespace and is reached directly via its own Service / public ingress.\n * - Talking directly avoids a hop through the backend and keeps the SDK\n * simple. The downside is that the consumer has to know two URLs (the\n * backend baseUrl and the PostgREST URL), which is what\n * `MitwayBaasConfig.postgrestUrl` is for.\n *\n * Auth: the SDK forwards the in-memory access token from the TokenManager\n * as `Authorization: Bearer <jwt>`. PostgREST verifies the JWT with the\n * tenant's JWT_SECRET (the same secret the backend uses, configured via the\n * helm chart secret).\n */\n\nimport { PostgrestClient } from '@supabase/postgrest-js';\nimport { TokenManager } from '../lib/token-manager';\nimport { MitwayBaasError } from '../types';\n\n/**\n * Create a fetch wrapper that injects the current access token (or the\n * anon key fallback) on every PostgREST request. The token is read from\n * the TokenManager on each request, so a sign-in/sign-out picks up\n * automatically without re-creating the client.\n */\nfunction createAuthedFetch(\n tokenManager: TokenManager,\n anonKey: string | undefined,\n): typeof fetch {\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const headers = new Headers(init?.headers);\n if (!headers.has('Authorization')) {\n const token = tokenManager.getAccessToken() ?? anonKey;\n if (token) {\n headers.set('Authorization', `Bearer ${token}`);\n }\n }\n return fetch(input as any, { ...init, headers });\n };\n}\n\nexport class Database {\n private postgrest: PostgrestClient<any, any, any> | null;\n private postgrestUrl: string | undefined;\n\n constructor(\n tokenManager: TokenManager,\n postgrestUrl: string | undefined,\n anonKey: string | undefined,\n ) {\n this.postgrestUrl = postgrestUrl;\n if (postgrestUrl) {\n this.postgrest = new PostgrestClient<any, any, any>(postgrestUrl, {\n fetch: createAuthedFetch(tokenManager, anonKey),\n headers: {},\n });\n } else {\n this.postgrest = null;\n }\n }\n\n private requireClient(): PostgrestClient<any, any, any> {\n if (!this.postgrest) {\n throw new MitwayBaasError(\n 'Database is not configured. Pass `postgrestUrl` in the SDK config to enable database operations.',\n 500,\n 'DATABASE_NOT_CONFIGURED',\n );\n }\n return this.postgrest;\n }\n\n /**\n * Build a PostgREST query against a table.\n *\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 * @example\n * const { data, error } = await client.database\n * .from('posts')\n * .insert({ title: 'Hello', content: 'World' })\n * .select()\n * .single();\n */\n from(table: string) {\n return this.requireClient().from(table);\n }\n\n /**\n * Call a PostgreSQL stored function (RPC).\n *\n * @example\n * const { data, error } = await client.database\n * .rpc('get_user_stats', { user_id: 123 });\n */\n rpc(\n fn: string,\n args?: Record<string, unknown>,\n options?: { head?: boolean; get?: boolean; count?: 'exact' | 'planned' | 'estimated' },\n ) {\n return this.requireClient().rpc(fn, args, options);\n }\n\n /**\n * The PostgREST URL the database client is talking to, or undefined if\n * the database module is not configured.\n */\n getUrl(): string | undefined {\n return this.postgrestUrl;\n }\n}\n","import { MitwayBaasConfig } from './types';\nimport { HttpClient } from './lib/http-client';\nimport { Logger } from './lib/logger';\nimport { TokenManager } from './lib/token-manager';\nimport { Auth } from './modules/auth';\nimport { Database } from './modules/database';\n\n/**\n * MITWAY-BaaS SDK client.\n *\n * @example\n * ```typescript\n * import { createClient } from '@mitway-baas/sdk';\n *\n * const client = createClient({\n * baseUrl: 'https://acme.api.dev.nttmitway.com', // backend (auth)\n * postgrestUrl: 'https://acme.db.dev.nttmitway.com', // postgrest (db)\n * anonKey: 'eyJhbGciOiJIUzI1NiIs...', // optional\n * });\n *\n * // Auth\n * const { data: session, error } = await client.auth.signInWithPassword({\n * email: 'a@b.com',\n * password: 'pw',\n * });\n *\n * // Database\n * const { data, error: dbError } = await client.database\n * .from('posts')\n * .select('*')\n * .eq('user_id', session.user.id)\n * .order('created_at', { ascending: false });\n * ```\n */\nexport class MitwayBaasClient {\n private http: HttpClient;\n private tokenManager: TokenManager;\n public readonly auth: Auth;\n public readonly database: Database;\n\n constructor(config: MitwayBaasConfig = {}) {\n const logger = new Logger(config.debug);\n this.tokenManager = new TokenManager();\n this.http = new HttpClient(config, this.tokenManager, logger);\n this.auth = new Auth(this.http, this.tokenManager);\n this.database = new Database(this.tokenManager, config.postgrestUrl, config.anonKey);\n }\n\n /**\n * Escape hatch for callers that need to make custom requests against the\n * backend without going through `auth` or `database`.\n */\n getHttpClient(): HttpClient {\n return this.http;\n }\n}\n","/**\n * @mitway-baas/sdk — TypeScript SDK for the MITWAY-BaaS backend.\n *\n * Currently ships:\n * - auth (signUp, signInWithPassword, signOut, refreshSession, getSession, getUser)\n * - database (PostgREST-backed query builder via @supabase/postgrest-js)\n *\n * Not yet included (no backend support):\n * - storage\n * - functions\n * - email\n * - ai\n * - realtime\n *\n * @packageDocumentation\n */\n\nexport { MitwayBaasClient } from './client';\n\nimport { MitwayBaasClient } from './client';\nimport { MitwayBaasConfig } from './types';\n\n/**\n * Factory function for creating SDK clients (Supabase-style).\n *\n * @example\n * ```typescript\n * import { createClient } from '@mitway-baas/sdk';\n *\n * const client = createClient({\n * baseUrl: 'https://acme.api.dev.nttmitway.com',\n * postgrestUrl: 'https://acme.db.dev.nttmitway.com',\n * });\n * ```\n */\nexport function createClient(config: MitwayBaasConfig): MitwayBaasClient {\n return new MitwayBaasClient(config);\n}\n\n// Default export for `import client from '@mitway-baas/sdk'`\nexport default MitwayBaasClient;\n\n// Public types\nexport type {\n MitwayBaasConfig,\n AuthSession,\n AuthRefreshResponse,\n ApiError,\n} from './types';\nexport { MitwayBaasError } from './types';\n\n// Re-export module classes for advanced/TypeScript-friendly usage\nexport { Auth } from './modules/auth';\nexport type { SignUpRequest, SignInRequest, AuthResponse, AuthResult } from './modules/auth';\nexport { Database } from './modules/database';\n\n// Re-export low-level helpers (most consumers won't need these)\nexport { HttpClient } from './lib/http-client';\nexport { TokenManager } from './lib/token-manager';\nexport { Logger } from './lib/logger';\n\n// Public User shape — inlined in lib/user so this package has no\n// MITWAY-BaaS workspace dependencies.\nexport type { User } from './lib/user';\n"],"mappings":"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","names":["timer"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/lib/logger.ts","../src/lib/token-manager.ts","../src/lib/http-client.ts","../src/modules/auth.ts","../src/modules/database.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["/**\n * MITWAY-BaaS SDK types — only SDK-specific shapes live here.\n * The `User` shape is inlined in `./lib/user` so this package has zero\n * MITWAY-BaaS workspace dependencies.\n */\n\nimport type { User } from './lib/user';\n\nexport interface MitwayBaasConfig {\n /**\n * Base URL of the MITWAY-BaaS backend. In production this is typically\n * `https://{cliente}.api.dev.nttmitway.com` (or the equivalent pro\n * domain). The SDK routes all traffic — auth, database (via the\n * backend's PostgREST proxy at `/api/database/records/*`), and future\n * storage/functions — through this one URL.\n *\n * @default \"http://localhost:7130\"\n */\n baseUrl?: string;\n\n /**\n * Anonymous JWT (signed by the tenant's JWT_SECRET, role = \"anon\").\n * Used as a fallback Bearer token for unauthenticated requests when no\n * user session is active.\n */\n anonKey?: string;\n\n /**\n * Custom fetch implementation. Useful in Node < 18 or test environments.\n * Defaults to `globalThis.fetch`.\n */\n fetch?: typeof fetch;\n\n /**\n * Custom default headers included on every request.\n */\n headers?: Record<string, string>;\n\n /**\n * Enable debug logging. `true` logs to console; pass a function to receive\n * log lines instead.\n */\n debug?: boolean | ((message: string, ...args: any[]) => void);\n\n /**\n * Per-request timeout in milliseconds. 0 disables the timeout.\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Number of retry attempts on network errors and 5xx responses. Client\n * errors (4xx) are never retried. 0 disables retries.\n * @default 3\n */\n retryCount?: number;\n\n /**\n * Initial delay before the first retry, in ms. Doubles each attempt with\n * ±15% jitter.\n * @default 500\n */\n retryDelay?: number;\n\n /**\n * Automatically refresh the access token on 401 INVALID_TOKEN responses\n * and retry the original request.\n * @default true\n */\n autoRefreshToken?: boolean;\n}\n\n/**\n * Active user session in memory. Mirrors what the auth endpoints return.\n */\nexport interface AuthSession {\n user: User;\n accessToken: string;\n expiresAt?: Date;\n}\n\n/**\n * Minimal payload that auth refresh endpoints emit. The SDK uses this to\n * refresh the in-memory session.\n */\nexport interface AuthRefreshResponse {\n user: User;\n accessToken: string;\n refreshToken?: string;\n csrfToken?: string;\n}\n\n/**\n * The `{ data, error }` envelope used by the MITWAY-BaaS backend on every\n * response. The SDK unwraps `data` for happy-path returns and converts\n * `error` into a `MitwayBaasError`.\n */\nexport interface ApiError {\n error: string;\n message: string;\n statusCode: number;\n nextActions?: string;\n}\n\nexport class MitwayBaasError extends Error {\n public statusCode: number;\n public error: string;\n public nextActions?: string;\n\n constructor(\n message: string,\n statusCode: number,\n error: string,\n nextActions?: string,\n ) {\n super(message);\n this.name = 'MitwayBaasError';\n this.statusCode = statusCode;\n this.error = error;\n this.nextActions = nextActions;\n }\n\n static fromApiError(apiError: ApiError): MitwayBaasError {\n return new MitwayBaasError(\n apiError.message,\n apiError.statusCode,\n apiError.error,\n apiError.nextActions,\n );\n }\n}\n","/**\n * Debug logger for the MITWAY-BaaS SDK.\n *\n * Logs HTTP request/response details with automatic redaction of sensitive\n * headers and body fields. Disabled by default; pass `debug: true` (or a\n * custom log function) on the SDK config to enable.\n */\n\ntype LogFunction = (message: string, ...args: any[]) => void;\n\nconst SENSITIVE_HEADERS = ['authorization', 'x-api-key', 'cookie', 'set-cookie'];\n\nconst SENSITIVE_BODY_KEYS = [\n 'password', 'token', 'accesstoken', 'refreshtoken',\n 'authorization', 'secret', 'apikey', 'api_key',\n 'email', 'ssn', 'creditcard', 'credit_card',\n];\n\nfunction redactHeaders(headers: Record<string, string>): Record<string, string> {\n const redacted: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (SENSITIVE_HEADERS.includes(key.toLowerCase())) {\n redacted[key] = '***REDACTED***';\n } else {\n redacted[key] = value;\n }\n }\n return redacted;\n}\n\nfunction sanitizeBody(body: any): any {\n if (body === null || body === undefined) return body;\n if (typeof body === 'string') {\n try {\n const parsed = JSON.parse(body);\n return sanitizeBody(parsed);\n } catch {\n return body;\n }\n }\n if (Array.isArray(body)) return body.map(sanitizeBody);\n if (typeof body === 'object') {\n const sanitized: Record<string, any> = {};\n for (const [key, value] of Object.entries(body)) {\n if (SENSITIVE_BODY_KEYS.includes(key.toLowerCase().replace(/[-_]/g, ''))) {\n sanitized[key] = '***REDACTED***';\n } else {\n sanitized[key] = sanitizeBody(value);\n }\n }\n return sanitized;\n }\n return body;\n}\n\nfunction formatBody(body: any): string {\n if (body === undefined || body === null) return '';\n if (typeof body === 'string') {\n try {\n return JSON.stringify(JSON.parse(body), null, 2);\n } catch {\n return body;\n }\n }\n if (typeof FormData !== 'undefined' && body instanceof FormData) {\n return '[FormData]';\n }\n try {\n return JSON.stringify(body, null, 2);\n } catch {\n return '[Unserializable body]';\n }\n}\n\nexport class Logger {\n public enabled: boolean;\n private customLog: LogFunction | null;\n\n constructor(debug?: boolean | LogFunction) {\n if (typeof debug === 'function') {\n this.enabled = true;\n this.customLog = debug;\n } else {\n this.enabled = !!debug;\n this.customLog = null;\n }\n }\n\n log(message: string, ...args: any[]): void {\n if (!this.enabled) return;\n const formatted = `[MITWAY-BaaS Debug] ${message}`;\n if (this.customLog) {\n this.customLog(formatted, ...args);\n } else {\n console.log(formatted, ...args);\n }\n }\n\n warn(message: string, ...args: any[]): void {\n if (!this.enabled) return;\n const formatted = `[MITWAY-BaaS Debug] ${message}`;\n if (this.customLog) {\n this.customLog(formatted, ...args);\n } else {\n console.warn(formatted, ...args);\n }\n }\n\n error(message: string, ...args: any[]): void {\n if (!this.enabled) return;\n const formatted = `[MITWAY-BaaS Debug] ${message}`;\n if (this.customLog) {\n this.customLog(formatted, ...args);\n } else {\n console.error(formatted, ...args);\n }\n }\n\n logRequest(\n method: string,\n url: string,\n headers?: Record<string, string>,\n body?: any\n ): void {\n if (!this.enabled) return;\n const parts: string[] = [`→ ${method} ${url}`];\n if (headers && Object.keys(headers).length > 0) {\n parts.push(` Headers: ${JSON.stringify(redactHeaders(headers))}`);\n }\n const formattedBody = formatBody(sanitizeBody(body));\n if (formattedBody) {\n const truncated = formattedBody.length > 1000\n ? formattedBody.slice(0, 1000) + '... [truncated]'\n : formattedBody;\n parts.push(` Body: ${truncated}`);\n }\n this.log(parts.join('\\n'));\n }\n\n logResponse(\n method: string,\n url: string,\n status: number,\n durationMs: number,\n body?: any\n ): void {\n if (!this.enabled) return;\n const parts: string[] = [\n `← ${method} ${url} ${status} (${durationMs}ms)`,\n ];\n const formattedBody = formatBody(sanitizeBody(body));\n if (formattedBody) {\n const truncated = formattedBody.length > 1000\n ? formattedBody.slice(0, 1000) + '... [truncated]'\n : formattedBody;\n parts.push(` Body: ${truncated}`);\n }\n if (status >= 400) {\n this.error(parts.join('\\n'));\n } else {\n this.log(parts.join('\\n'));\n }\n }\n}\n","/**\n * Token Manager for the MITWAY-BaaS SDK.\n *\n * In-memory storage for the access token + user. Browser CSRF token lives\n * in a cookie so the cookie-based refresh flow works across page reloads.\n */\n\nimport type { User } from './user';\nimport type { AuthSession } from '../types';\n\nexport const CSRF_TOKEN_COOKIE = 'mitway_baas_csrf_token';\n\nexport function getCsrfToken(): string | null {\n if (typeof document === 'undefined') return null;\n const match = document.cookie\n .split(';')\n .find((c) => c.trim().startsWith(`${CSRF_TOKEN_COOKIE}=`));\n if (!match) return null;\n return match.split('=')[1] || null;\n}\n\nexport function setCsrfToken(token: string): void {\n if (typeof document === 'undefined') return;\n const maxAge = 7 * 24 * 60 * 60; // 7 days\n const secure =\n typeof window !== 'undefined' && window.location.protocol === 'https:'\n ? '; Secure'\n : '';\n document.cookie = `${CSRF_TOKEN_COOKIE}=${encodeURIComponent(token)}; path=/; max-age=${maxAge}; SameSite=Lax${secure}`;\n}\n\nexport function clearCsrfToken(): void {\n if (typeof document === 'undefined') return;\n const secure =\n typeof window !== 'undefined' && window.location.protocol === 'https:'\n ? '; Secure'\n : '';\n document.cookie = `${CSRF_TOKEN_COOKIE}=; path=/; max-age=0; SameSite=Lax${secure}`;\n}\n\nexport class TokenManager {\n private accessToken: string | null = null;\n private user: User | null = null;\n\n /** Fired when the access token changes (used by long-lived consumers). */\n onTokenChange: (() => void) | null = null;\n\n saveSession(session: AuthSession): void {\n const tokenChanged = session.accessToken !== this.accessToken;\n this.accessToken = session.accessToken;\n this.user = session.user;\n if (tokenChanged && this.onTokenChange) {\n this.onTokenChange();\n }\n }\n\n getSession(): AuthSession | null {\n if (!this.accessToken || !this.user) return null;\n return {\n accessToken: this.accessToken,\n user: this.user,\n };\n }\n\n getAccessToken(): string | null {\n return this.accessToken;\n }\n\n setAccessToken(token: string): void {\n const tokenChanged = token !== this.accessToken;\n this.accessToken = token;\n if (tokenChanged && this.onTokenChange) {\n this.onTokenChange();\n }\n }\n\n getUser(): User | null {\n return this.user;\n }\n\n setUser(user: User): void {\n this.user = user;\n }\n\n clearSession(): void {\n const hadToken = this.accessToken !== null;\n this.accessToken = null;\n this.user = null;\n if (hadToken && this.onTokenChange) {\n this.onTokenChange();\n }\n }\n}\n","/**\n * HttpClient with retry, timeout, abort signal composition, and automatic\n * token refresh on 401 INVALID_TOKEN responses.\n *\n * Ported from the InsForge SDK with rebranding plus one route change:\n * the refresh endpoint is `/api/auth/refresh` (MITWAY-BaaS) instead of\n * `/api/auth/sessions/current` (InsForge).\n */\n\nimport {\n MitwayBaasConfig,\n ApiError,\n MitwayBaasError,\n AuthRefreshResponse,\n} from '../types';\nimport { Logger } from './logger';\nimport {\n clearCsrfToken,\n getCsrfToken,\n setCsrfToken,\n TokenManager,\n} from './token-manager';\n\ntype JsonRequestBody = Record<string, unknown> | unknown[] | null;\n\nexport interface RequestOptions extends Omit<RequestInit, 'body'> {\n params?: Record<string, string>;\n body?: RequestInit['body'] | JsonRequestBody;\n /**\n * Allow retrying non-idempotent requests (POST, PATCH). Off by default to\n * prevent duplicate writes on transient server errors.\n */\n idempotent?: boolean;\n}\n\nconst RETRYABLE_STATUS_CODES = new Set([500, 502, 503, 504]);\nconst IDEMPOTENT_METHODS = new Set(['GET', 'HEAD', 'PUT', 'DELETE', 'OPTIONS']);\n\nexport class HttpClient {\n public readonly baseUrl: string;\n public readonly fetch: typeof fetch;\n private defaultHeaders: Record<string, string>;\n private anonKey: string | undefined;\n private userToken: string | null = null;\n private logger: Logger;\n private autoRefreshToken: boolean = true;\n private isRefreshing: boolean = false;\n private refreshPromise: Promise<AuthRefreshResponse> | null = null;\n private tokenManager: TokenManager;\n private refreshToken: string | null = null;\n private timeout: number;\n private retryCount: number;\n private retryDelay: number;\n\n constructor(\n config: MitwayBaasConfig,\n tokenManager?: TokenManager,\n logger?: Logger,\n ) {\n this.baseUrl = config.baseUrl || 'http://localhost:7130';\n this.autoRefreshToken = config.autoRefreshToken ?? true;\n this.fetch =\n config.fetch ||\n (globalThis.fetch\n ? globalThis.fetch.bind(globalThis)\n : (undefined as any));\n this.anonKey = config.anonKey;\n this.defaultHeaders = {\n ...config.headers,\n };\n this.tokenManager = tokenManager ?? new TokenManager();\n this.logger = logger || new Logger(false);\n this.timeout = config.timeout ?? 30_000;\n this.retryCount = config.retryCount ?? 3;\n this.retryDelay = config.retryDelay ?? 500;\n\n if (!this.fetch) {\n throw new Error(\n 'Fetch is not available. Provide a fetch implementation in the SDK 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 if (key === 'select') {\n // Normalize PostgREST select syntax (whitespace inside relationships).\n let normalizedValue = value.replace(/\\s+/g, ' ').trim();\n normalizedValue = normalizedValue\n .replace(/\\s*\\(\\s*/g, '(')\n .replace(/\\s*\\)\\s*/g, ')')\n .replace(/\\(\\s+/g, '(')\n .replace(/\\s+\\)/g, ')')\n .replace(/,\\s+(?=[^()]*\\))/g, ',');\n url.searchParams.append(key, normalizedValue);\n } else {\n url.searchParams.append(key, value);\n }\n });\n }\n return url.toString();\n }\n\n private isRetryableStatus(status: number): boolean {\n return RETRYABLE_STATUS_CODES.has(status);\n }\n\n private computeRetryDelay(attempt: number): number {\n const base = this.retryDelay * Math.pow(2, attempt - 1);\n const jitter = base * (0.85 + Math.random() * 0.3);\n return Math.round(jitter);\n }\n\n private async handleRequest<T>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n const {\n params,\n headers = {},\n body,\n signal: callerSignal,\n ...fetchOptions\n } = options as RequestOptions & { signal?: AbortSignal };\n\n const url = this.buildUrl(path, params);\n const startTime = Date.now();\n const canRetry =\n IDEMPOTENT_METHODS.has(method.toUpperCase()) ||\n options.idempotent === true;\n const maxAttempts = canRetry ? this.retryCount : 0;\n\n const requestHeaders: Record<string, string> = {\n ...this.defaultHeaders,\n };\n\n const authToken = this.userToken || this.anonKey;\n if (authToken) {\n requestHeaders['Authorization'] = `Bearer ${authToken}`;\n }\n\n let processedBody: any;\n if (body !== undefined) {\n if (typeof FormData !== 'undefined' && body instanceof FormData) {\n processedBody = body;\n } else {\n if (method !== 'GET') {\n requestHeaders['Content-Type'] = 'application/json;charset=UTF-8';\n }\n processedBody = JSON.stringify(body);\n }\n }\n\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n requestHeaders[key] = value;\n });\n } else if (Array.isArray(headers)) {\n headers.forEach(([key, value]) => {\n requestHeaders[key] = value;\n });\n } else {\n Object.assign(requestHeaders, headers);\n }\n\n this.logger.logRequest(method, url, requestHeaders, processedBody);\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxAttempts; attempt++) {\n if (attempt > 0) {\n const delay = this.computeRetryDelay(attempt);\n this.logger.warn(\n `Retry ${attempt}/${maxAttempts} for ${method} ${url} in ${delay}ms`,\n );\n if (callerSignal?.aborted) throw callerSignal.reason;\n await new Promise<void>((resolve, reject) => {\n const onAbort = () => {\n clearTimeout(timer);\n reject(callerSignal!.reason);\n };\n const timer = setTimeout(() => {\n if (callerSignal)\n callerSignal.removeEventListener('abort', onAbort);\n resolve();\n }, delay);\n if (callerSignal) {\n callerSignal.addEventListener('abort', onAbort, { once: true });\n }\n });\n }\n\n let controller: AbortController | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n if (this.timeout > 0 || callerSignal) {\n controller = new AbortController();\n\n if (this.timeout > 0) {\n timer = setTimeout(() => controller!.abort(), this.timeout);\n }\n\n if (callerSignal) {\n if (callerSignal.aborted) {\n controller.abort(callerSignal.reason);\n } else {\n const onCallerAbort = () => controller!.abort(callerSignal!.reason);\n callerSignal.addEventListener('abort', onCallerAbort, { once: true });\n controller.signal.addEventListener(\n 'abort',\n () => {\n callerSignal!.removeEventListener('abort', onCallerAbort);\n },\n { once: true },\n );\n }\n }\n }\n\n try {\n const response = await this.fetch(url, {\n method,\n headers: requestHeaders,\n body: processedBody,\n ...fetchOptions,\n ...(controller ? { signal: controller.signal } : {}),\n });\n\n if (this.isRetryableStatus(response.status) && attempt < maxAttempts) {\n if (timer !== undefined) clearTimeout(timer);\n await response.body?.cancel();\n lastError = new MitwayBaasError(\n `Server error: ${response.status} ${response.statusText}`,\n response.status,\n 'SERVER_ERROR',\n );\n continue;\n }\n\n if (response.status === 204) {\n if (timer !== undefined) clearTimeout(timer);\n return undefined as T;\n }\n\n let data: any;\n const contentType = response.headers.get('content-type');\n try {\n if (contentType?.includes('json')) {\n data = await response.json();\n } else {\n data = await response.text();\n }\n } catch (parseErr: any) {\n if (timer !== undefined) clearTimeout(timer);\n throw new MitwayBaasError(\n `Failed to parse response body: ${parseErr?.message || 'Unknown error'}`,\n response.status,\n response.ok ? 'PARSE_ERROR' : 'REQUEST_FAILED',\n );\n }\n\n if (timer !== undefined) clearTimeout(timer);\n\n if (!response.ok) {\n this.logger.logResponse(\n method,\n url,\n response.status,\n Date.now() - startTime,\n data,\n );\n if (data && typeof data === 'object' && 'error' in data) {\n if (!data.statusCode && !data.status) {\n data.statusCode = response.status;\n }\n const error = MitwayBaasError.fromApiError(data as ApiError);\n Object.keys(data).forEach((key) => {\n if (key !== 'error' && key !== 'message' && key !== 'statusCode') {\n (error as any)[key] = data[key];\n }\n });\n throw error;\n }\n throw new MitwayBaasError(\n `Request failed: ${response.statusText}`,\n response.status,\n 'REQUEST_FAILED',\n );\n }\n\n this.logger.logResponse(\n method,\n url,\n response.status,\n Date.now() - startTime,\n data,\n );\n return data as T;\n } catch (err: any) {\n if (timer !== undefined) clearTimeout(timer);\n\n if (err?.name === 'AbortError') {\n if (\n controller &&\n controller.signal.aborted &&\n this.timeout > 0 &&\n !callerSignal?.aborted\n ) {\n throw new MitwayBaasError(\n `Request timed out after ${this.timeout}ms`,\n 408,\n 'REQUEST_TIMEOUT',\n );\n }\n throw err;\n }\n\n if (err instanceof MitwayBaasError) {\n throw err;\n }\n\n if (attempt < maxAttempts) {\n lastError = err;\n continue;\n }\n\n throw new MitwayBaasError(\n `Network request failed: ${err?.message || 'Unknown error'}`,\n 0,\n 'NETWORK_ERROR',\n );\n }\n }\n\n throw (\n lastError ||\n new MitwayBaasError(\n 'Request failed after all retry attempts',\n 0,\n 'NETWORK_ERROR',\n )\n );\n }\n\n async request<T>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n try {\n return await this.handleRequest<T>(method, path, { ...options });\n } catch (error) {\n if (\n error instanceof MitwayBaasError &&\n error.statusCode === 401 &&\n error.error === 'INVALID_TOKEN' &&\n this.autoRefreshToken\n ) {\n try {\n const newTokenData = await this.handleTokenRefresh();\n this.setAuthToken(newTokenData.accessToken);\n this.tokenManager!.saveSession(newTokenData);\n if (newTokenData.csrfToken) {\n setCsrfToken(newTokenData.csrfToken);\n }\n if (newTokenData.refreshToken) {\n this.setRefreshToken(newTokenData.refreshToken);\n }\n return await this.handleRequest<T>(method, path, { ...options });\n } catch (refreshError) {\n this.tokenManager.clearSession();\n this.userToken = null;\n this.refreshToken = null;\n clearCsrfToken();\n throw refreshError;\n }\n }\n throw error;\n }\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 this.userToken = token;\n }\n\n setRefreshToken(token: string | null) {\n this.refreshToken = token;\n }\n\n getHeaders(): Record<string, string> {\n const headers = { ...this.defaultHeaders };\n const authToken = this.userToken || this.anonKey;\n if (authToken) {\n headers['Authorization'] = `Bearer ${authToken}`;\n }\n return headers;\n }\n\n /**\n * Refresh the current session by calling the MITWAY-BaaS refresh endpoint.\n * Note: the route is `/api/auth/refresh` (POST), not the InsForge\n * `/api/auth/sessions/current` route. Returns the new access token + user.\n */\n async handleTokenRefresh(): Promise<AuthRefreshResponse> {\n if (this.isRefreshing) {\n return this.refreshPromise!;\n }\n\n this.isRefreshing = true;\n this.refreshPromise = (async () => {\n try {\n const csrfToken = getCsrfToken();\n const body = this.refreshToken\n ? { refreshToken: this.refreshToken }\n : undefined;\n const response = await this.handleRequest<AuthRefreshResponse>(\n 'POST',\n '/api/auth/refresh',\n {\n body,\n headers: csrfToken ? { 'X-CSRF-Token': csrfToken } : {},\n credentials: 'include',\n },\n );\n return response;\n } finally {\n this.isRefreshing = false;\n this.refreshPromise = null;\n }\n })();\n\n return this.refreshPromise;\n }\n}\n","/**\n * Auth module — MITWAY-BaaS specific.\n *\n * Targets the routes that the MITWAY-BaaS backend currently exposes:\n * POST /api/auth/register → signUp\n * POST /api/auth/login → signInWithPassword\n * POST /api/auth/logout → signOut\n * POST /api/auth/refresh → refreshSession (also auto-called by HttpClient)\n *\n * OAuth, email verification, password reset, and the InsForge-only\n * profile/sessions admin endpoints are NOT included — the backend does not\n * implement them yet. When it does, port the corresponding methods from the\n * upstream InsForge SDK (`InsForge/InsForge-sdk-js/src/modules/auth/auth.ts`).\n */\n\nimport type { User } from '../lib/user';\nimport { HttpClient } from '../lib/http-client';\nimport { TokenManager, setCsrfToken, clearCsrfToken } from '../lib/token-manager';\nimport { AuthSession, MitwayBaasError } from '../types';\n\nexport interface SignUpRequest {\n email: string;\n password: string;\n name?: string;\n}\n\nexport interface SignInRequest {\n email: string;\n password: string;\n}\n\n/**\n * The shape the backend returns from /register, /login, and /refresh. Mirrors\n * what the existing backend handlers send: `{ user, accessToken, refreshToken,\n * csrfToken? }` wrapped in the standard `{ data, error }` envelope. The SDK\n * unwraps the envelope before reaching this type, so consumers see the raw\n * shape.\n */\nexport interface AuthResponse {\n user: User;\n accessToken: string;\n refreshToken?: string;\n csrfToken?: string;\n}\n\nexport type AuthResult<T> = {\n data: T | null;\n error: MitwayBaasError | null;\n};\n\nfunction wrapError<T>(error: unknown, fallbackMessage: string): AuthResult<T> {\n if (error instanceof MitwayBaasError) {\n return { data: null, error };\n }\n return {\n data: null,\n error: new MitwayBaasError(\n error instanceof Error ? error.message : fallbackMessage,\n 500,\n 'AUTH_ERROR',\n ),\n };\n}\n\nexport class Auth {\n constructor(\n private http: HttpClient,\n private tokenManager: TokenManager,\n ) {}\n\n /**\n * Persist the session in memory + HttpClient defaults so subsequent\n * requests carry the new bearer token automatically.\n */\n private saveSessionFromResponse(response: AuthResponse): void {\n const session: AuthSession = {\n accessToken: response.accessToken,\n user: response.user,\n };\n if (response.csrfToken) {\n setCsrfToken(response.csrfToken);\n }\n this.tokenManager.saveSession(session);\n this.http.setAuthToken(response.accessToken);\n this.http.setRefreshToken(response.refreshToken ?? null);\n }\n\n /**\n * Create a new user account and start a session.\n *\n * @example\n * const { data, error } = await client.auth.signUp({\n * email: 'a@b.com',\n * password: 'a-strong-password',\n * name: 'Alice'\n * });\n */\n async signUp(request: SignUpRequest): Promise<AuthResult<AuthResponse>> {\n try {\n const response = await this.http.post<AuthResponse>(\n '/api/auth/register',\n request,\n { credentials: 'include' },\n );\n if (response?.accessToken && response.user) {\n this.saveSessionFromResponse(response);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<AuthResponse>(error, 'Sign up failed');\n }\n }\n\n /**\n * Sign in with email + password and start a session.\n */\n async signInWithPassword(\n request: SignInRequest,\n ): Promise<AuthResult<AuthResponse>> {\n try {\n const response = await this.http.post<AuthResponse>(\n '/api/auth/login',\n request,\n { credentials: 'include' },\n );\n if (response?.accessToken && response.user) {\n this.saveSessionFromResponse(response);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<AuthResponse>(error, 'Sign in failed');\n }\n }\n\n /**\n * End the current session. Clears in-memory state even if the backend\n * call fails (network/offline).\n */\n async signOut(): Promise<{ error: MitwayBaasError | null }> {\n try {\n try {\n await this.http.post('/api/auth/logout', undefined, {\n credentials: 'include',\n });\n } catch {\n // Backend logout failure is non-fatal — local state still clears.\n }\n this.tokenManager.clearSession();\n this.http.setAuthToken(null);\n this.http.setRefreshToken(null);\n clearCsrfToken();\n return { error: null };\n } catch {\n return {\n error: new MitwayBaasError('Failed to sign out', 500, 'SIGNOUT_ERROR'),\n };\n }\n }\n\n /**\n * Manually refresh the current session. The HttpClient will call this\n * automatically on 401 INVALID_TOKEN responses; consumers usually do\n * not need to call it directly.\n */\n async refreshSession(): Promise<AuthResult<AuthResponse>> {\n try {\n const response = await this.http.handleTokenRefresh();\n if (response?.accessToken && response.user) {\n this.saveSessionFromResponse(response);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<AuthResponse>(error, 'Session refresh failed');\n }\n }\n\n /**\n * Get the current in-memory session, or null if the user is not signed in.\n * Synchronous — does not hit the network.\n */\n getSession(): AuthSession | null {\n return this.tokenManager.getSession();\n }\n\n /**\n * Get the current in-memory user, or null if not signed in.\n */\n getUser(): User | null {\n return this.tokenManager.getUser();\n }\n}\n","/**\n * Database module — wraps `@supabase/postgrest-js` and transforms its\n * outbound URLs so they hit the MITWAY-BaaS backend proxy instead of\n * PostgREST directly.\n *\n * Why via the backend (not direct to PostgREST):\n * PostgREST is deployed as an internal ClusterIP Service per cliente\n * (`mitway-baas-{cliente}-postgrest:3000`), never publicly exposed. The\n * backend forwards incoming `/api/database/records/*` and\n * `/api/database/rpc/*` requests to PostgREST over the cluster network.\n * This collapses the per-cliente public surface into a single URL:\n * `https://{cliente}.api.dev.nttmitway.com`.\n *\n * The pattern is copied from the InsForge SDK's `database-postgrest.ts`:\n * point postgrest-js at a dummy URL, intercept fetch, rewrite.\n *\n * Auth:\n * On every request the fetch wrapper reads the current access token\n * from the TokenManager (or falls back to the SDK's configured\n * `anonKey`) and forwards it as `Authorization: Bearer <jwt>`. The\n * MITWAY-BaaS backend's api-key middleware accepts it, the proxy\n * forwards it to PostgREST, and PostgREST verifies it with the shared\n * tenant JWT_SECRET and enforces RLS policies based on the role claim.\n */\n\nimport { PostgrestClient } from '@supabase/postgrest-js';\nimport { HttpClient } from '../lib/http-client';\nimport { TokenManager } from '../lib/token-manager';\nimport { MitwayBaasError } from '../types';\n\n/**\n * Custom fetch that:\n * 1. Rewrites the URL from postgrest-js's dummy format (`http://dummy/posts`)\n * to the MITWAY-BaaS backend proxy path\n * (`{baseUrl}/api/database/records/posts` or\n * `{baseUrl}/api/database/rpc/{fn}`).\n * 2. Injects the current access token (or anon key fallback) as the\n * `Authorization: Bearer <jwt>` header if one isn't already set.\n */\nfunction createMitwayBaasFetch(\n httpClient: HttpClient,\n tokenManager: TokenManager,\n anonKey: string | undefined,\n): typeof fetch {\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const url = typeof input === 'string' ? input : input.toString();\n const urlObj = new URL(url);\n\n // postgrest-js sends: http://dummy/tablename?params for tables\n // http://dummy/rpc/fnname?params for stored fns\n // Rewrite pathname to the backend proxy path. Strip the leading `/`\n // to make the join unambiguous.\n const pathname = urlObj.pathname.startsWith('/') ? urlObj.pathname.slice(1) : urlObj.pathname;\n const rpcMatch = pathname.match(/^rpc\\/(.+)$/);\n const endpoint = rpcMatch\n ? `/api/database/rpc/${rpcMatch[1]}`\n : `/api/database/records/${pathname}`;\n\n const targetUrl = `${httpClient.baseUrl}${endpoint}${urlObj.search}`;\n\n // Inject auth. Prefer the current user token, fall back to anonKey.\n // Don't overwrite Authorization if the caller already set one.\n const headers = new Headers(init?.headers);\n if (!headers.has('Authorization')) {\n const token = tokenManager.getAccessToken() ?? anonKey;\n if (token) {\n headers.set('Authorization', `Bearer ${token}`);\n }\n }\n\n return fetch(targetUrl, { ...init, headers });\n };\n}\n\nexport class Database {\n private postgrest: PostgrestClient<any, any, any>;\n private httpClient: HttpClient;\n\n constructor(\n httpClient: HttpClient,\n tokenManager: TokenManager,\n anonKey: string | undefined,\n ) {\n this.httpClient = httpClient;\n // The URL we pass to PostgrestClient is a dummy — the fetch wrapper\n // above rewrites every outgoing URL before it reaches the network.\n // Keeping it as `http://dummy` makes it obvious in stack traces that\n // nothing should ever actually dial this address.\n this.postgrest = new PostgrestClient<any, any, any>('http://dummy', {\n fetch: createMitwayBaasFetch(httpClient, tokenManager, anonKey),\n headers: {},\n });\n }\n\n /**\n * Build a PostgREST query against a table.\n *\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 * @example\n * const { data, error } = await client.database\n * .from('posts')\n * .insert({ title: 'Hello', content: 'World' })\n * .select()\n * .single();\n */\n from(table: string) {\n if (!table || typeof table !== 'string') {\n throw new MitwayBaasError(\n 'Database.from(table) requires a non-empty string',\n 400,\n 'INVALID_TABLE_NAME',\n );\n }\n return this.postgrest.from(table);\n }\n\n /**\n * Call a PostgreSQL stored function (RPC).\n *\n * @example\n * const { data, error } = await client.database\n * .rpc('get_user_stats', { user_id: 123 });\n */\n rpc(\n fn: string,\n args?: Record<string, unknown>,\n options?: { head?: boolean; get?: boolean; count?: 'exact' | 'planned' | 'estimated' },\n ) {\n return this.postgrest.rpc(fn, args, options);\n }\n\n /**\n * The backend base URL the database client is targeting. Useful for\n * debugging — the actual PostgREST instance is internal and not\n * reachable by the SDK directly.\n */\n getUrl(): string {\n return this.httpClient.baseUrl;\n }\n}\n","import { MitwayBaasConfig } from './types';\nimport { HttpClient } from './lib/http-client';\nimport { Logger } from './lib/logger';\nimport { TokenManager } from './lib/token-manager';\nimport { Auth } from './modules/auth';\nimport { Database } from './modules/database';\n\n/**\n * MITWAY-BaaS SDK client.\n *\n * @example\n * ```typescript\n * import { createClient } from '@mitway/sdk';\n *\n * const client = createClient({\n * baseUrl: 'https://acme.api.dev.nttmitway.com',\n * anonKey: 'eyJhbGciOiJIUzI1NiIs...', // optional\n * });\n *\n * // Auth\n * const { data: session, error } = await client.auth.signInWithPassword({\n * email: 'a@b.com',\n * password: 'pw',\n * });\n *\n * // Database — transparently routed through the backend proxy at\n * // /api/database/records/* (no separate PostgREST URL).\n * const { data, error: dbError } = await client.database\n * .from('posts')\n * .select('*')\n * .eq('user_id', session.user.id)\n * .order('created_at', { ascending: false });\n * ```\n */\nexport class MitwayBaasClient {\n private http: HttpClient;\n private tokenManager: TokenManager;\n public readonly auth: Auth;\n public readonly database: Database;\n\n constructor(config: MitwayBaasConfig = {}) {\n const logger = new Logger(config.debug);\n this.tokenManager = new TokenManager();\n this.http = new HttpClient(config, this.tokenManager, logger);\n this.auth = new Auth(this.http, this.tokenManager);\n this.database = new Database(this.http, this.tokenManager, config.anonKey);\n }\n\n /**\n * Escape hatch for callers that need to make custom requests against the\n * backend without going through `auth` or `database`.\n */\n getHttpClient(): HttpClient {\n return this.http;\n }\n}\n","/**\n * @mitway-baas/sdk — TypeScript SDK for the MITWAY-BaaS backend.\n *\n * Currently ships:\n * - auth (signUp, signInWithPassword, signOut, refreshSession, getSession, getUser)\n * - database (PostgREST-backed query builder via @supabase/postgrest-js)\n *\n * Not yet included (no backend support):\n * - storage\n * - functions\n * - email\n * - ai\n * - realtime\n *\n * @packageDocumentation\n */\n\nexport { MitwayBaasClient } from './client';\n\nimport { MitwayBaasClient } from './client';\nimport { MitwayBaasConfig } from './types';\n\n/**\n * Factory function for creating SDK clients (Supabase-style).\n *\n * @example\n * ```typescript\n * import { createClient } from '@mitway-baas/sdk';\n *\n * const client = createClient({\n * baseUrl: 'https://acme.api.dev.nttmitway.com',\n * postgrestUrl: 'https://acme.db.dev.nttmitway.com',\n * });\n * ```\n */\nexport function createClient(config: MitwayBaasConfig): MitwayBaasClient {\n return new MitwayBaasClient(config);\n}\n\n// Default export for `import client from '@mitway-baas/sdk'`\nexport default MitwayBaasClient;\n\n// Public types\nexport type {\n MitwayBaasConfig,\n AuthSession,\n AuthRefreshResponse,\n ApiError,\n} from './types';\nexport { MitwayBaasError } from './types';\n\n// Re-export module classes for advanced/TypeScript-friendly usage\nexport { Auth } from './modules/auth';\nexport type { SignUpRequest, SignInRequest, AuthResponse, AuthResult } from './modules/auth';\nexport { Database } from './modules/database';\n\n// Re-export low-level helpers (most consumers won't need these)\nexport { HttpClient } from './lib/http-client';\nexport { TokenManager } from './lib/token-manager';\nexport { Logger } from './lib/logger';\n\n// Public User shape — inlined in lib/user so this package has no\n// MITWAY-BaaS workspace dependencies.\nexport type { User } from './lib/user';\n"],"mappings":"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","names":["timer"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mitway/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "TypeScript/JavaScript client for MITWAY-BaaS — auth + database for end-user apps",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",