@mitway/sdk 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,18 +2,18 @@
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
- | `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 |
13
+ | `auth` | ✅ Working | `signUp`, `signInWithPassword`, `signOut`, `refreshSession`, `getSession`, `getUser`, `getCurrentUser`, `getProfile`, `setProfile` |
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
- | `functions` | Not yet | Backend has no `/api/functions/*` routes |
16
+ | `functions` | MCP only | Backend routes + MCP tools working. No SDK module — functions are managed by the agent, not by end-user apps |
17
17
  | `email` | ❌ Not yet | Backend has no `/api/email/*` routes |
18
18
  | `ai` | ❌ Not yet | Backend has no `/api/ai/*` routes |
19
19
  | `realtime` | ❌ Not yet | No realtime subsystem |
@@ -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
@@ -732,12 +732,68 @@ var Auth = class {
732
732
  getUser() {
733
733
  return this.tokenManager.getUser();
734
734
  }
735
+ /**
736
+ * Fetch the current user from the backend. Unlike getUser() which reads
737
+ * from memory, this makes a network request and returns the latest data.
738
+ */
739
+ async getCurrentUser() {
740
+ try {
741
+ const response = await this.http.get(
742
+ "/api/auth/sessions/current"
743
+ );
744
+ if (response?.user) {
745
+ const session = {
746
+ accessToken: this.tokenManager.getSession()?.accessToken ?? "",
747
+ user: response.user
748
+ };
749
+ this.tokenManager.saveSession(session);
750
+ }
751
+ return { data: response, error: null };
752
+ } catch (error) {
753
+ return wrapError(error, "Failed to get current user");
754
+ }
755
+ }
756
+ /**
757
+ * Get a user's profile by ID. Requires authentication.
758
+ */
759
+ async getProfile(userId) {
760
+ try {
761
+ const response = await this.http.get(`/api/auth/profiles/${encodeURIComponent(userId)}`);
762
+ return { data: response, error: null };
763
+ } catch (error) {
764
+ return wrapError(
765
+ error,
766
+ "Failed to get profile"
767
+ );
768
+ }
769
+ }
770
+ /**
771
+ * Update the current user's profile. Merges with existing profile data —
772
+ * only the fields you pass are updated, existing fields are preserved.
773
+ */
774
+ async setProfile(profile) {
775
+ try {
776
+ const response = await this.http.patch("/api/auth/profiles/current", { profile });
777
+ return { data: response, error: null };
778
+ } catch (error) {
779
+ return wrapError(
780
+ error,
781
+ "Failed to update profile"
782
+ );
783
+ }
784
+ }
735
785
  };
736
786
 
737
787
  // src/modules/database.ts
738
788
  var import_postgrest_js = require("@supabase/postgrest-js");
739
- function createAuthedFetch(tokenManager, anonKey) {
789
+ function createMitwayBaasFetch(httpClient, tokenManager, anonKey) {
740
790
  return async (input, init) => {
791
+ const url = typeof input === "string" ? input : input.toString();
792
+ const urlObj = new URL(url);
793
+ const pathname = urlObj.pathname.startsWith("/") ? urlObj.pathname.slice(1) : urlObj.pathname;
794
+ const rpcMatch = pathname.match(/^rpc\/(.+)$/);
795
+ const endpoint = rpcMatch ? `/api/database/rpc/${rpcMatch[1]}` : `/api/database/records/${pathname}`;
796
+ const targetUrl = `${httpClient.baseUrl}${endpoint}${urlObj.search}`;
741
797
  const headers = new Headers(init?.headers);
742
798
  if (!headers.has("Authorization")) {
743
799
  const token = tokenManager.getAccessToken() ?? anonKey;
@@ -745,32 +801,18 @@ function createAuthedFetch(tokenManager, anonKey) {
745
801
  headers.set("Authorization", `Bearer ${token}`);
746
802
  }
747
803
  }
748
- return fetch(input, { ...init, headers });
804
+ return fetch(targetUrl, { ...init, headers });
749
805
  };
750
806
  }
751
807
  var Database = class {
752
808
  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;
809
+ httpClient;
810
+ constructor(httpClient, tokenManager, anonKey) {
811
+ this.httpClient = httpClient;
812
+ this.postgrest = new import_postgrest_js.PostgrestClient("http://dummy", {
813
+ fetch: createMitwayBaasFetch(httpClient, tokenManager, anonKey),
814
+ headers: {}
815
+ });
774
816
  }
775
817
  /**
776
818
  * Build a PostgREST query against a table.
@@ -791,7 +833,14 @@ var Database = class {
791
833
  * .single();
792
834
  */
793
835
  from(table) {
794
- return this.requireClient().from(table);
836
+ if (!table || typeof table !== "string") {
837
+ throw new MitwayBaasError(
838
+ "Database.from(table) requires a non-empty string",
839
+ 400,
840
+ "INVALID_TABLE_NAME"
841
+ );
842
+ }
843
+ return this.postgrest.from(table);
795
844
  }
796
845
  /**
797
846
  * Call a PostgreSQL stored function (RPC).
@@ -801,14 +850,15 @@ var Database = class {
801
850
  * .rpc('get_user_stats', { user_id: 123 });
802
851
  */
803
852
  rpc(fn, args, options) {
804
- return this.requireClient().rpc(fn, args, options);
853
+ return this.postgrest.rpc(fn, args, options);
805
854
  }
806
855
  /**
807
- * The PostgREST URL the database client is talking to, or undefined if
808
- * the database module is not configured.
856
+ * The backend base URL the database client is targeting. Useful for
857
+ * debugging — the actual PostgREST instance is internal and not
858
+ * reachable by the SDK directly.
809
859
  */
810
860
  getUrl() {
811
- return this.postgrestUrl;
861
+ return this.httpClient.baseUrl;
812
862
  }
813
863
  };
814
864
 
@@ -823,7 +873,7 @@ var MitwayBaasClient = class {
823
873
  this.tokenManager = new TokenManager();
824
874
  this.http = new HttpClient(config, this.tokenManager, logger);
825
875
  this.auth = new Auth(this.http, this.tokenManager);
826
- this.database = new Database(this.tokenManager, config.postgrestUrl, config.anonKey);
876
+ this.database = new Database(this.http, this.tokenManager, config.anonKey);
827
877
  }
828
878
  /**
829
879
  * 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 * Fetch the current user from the backend. Unlike getUser() which reads\n * from memory, this makes a network request and returns the latest data.\n */\n async getCurrentUser(): Promise<AuthResult<{ user: User }>> {\n try {\n const response = await this.http.get<{ user: User }>(\n '/api/auth/sessions/current',\n );\n if (response?.user) {\n const session: AuthSession = {\n accessToken: this.tokenManager.getSession()?.accessToken ?? '',\n user: response.user,\n };\n this.tokenManager.saveSession(session);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<{ user: User }>(error, 'Failed to get current user');\n }\n }\n\n /**\n * Get a user's profile by ID. Requires authentication.\n */\n async getProfile(\n userId: string,\n ): Promise<AuthResult<{ id: string; profile: Record<string, unknown> | null }>> {\n try {\n const response = await this.http.get<{\n id: string;\n profile: Record<string, unknown> | null;\n }>(`/api/auth/profiles/${encodeURIComponent(userId)}`);\n return { data: response, error: null };\n } catch (error) {\n return wrapError<{ id: string; profile: Record<string, unknown> | null }>(\n error,\n 'Failed to get profile',\n );\n }\n }\n\n /**\n * Update the current user's profile. Merges with existing profile data —\n * only the fields you pass are updated, existing fields are preserved.\n */\n async setProfile(\n profile: Record<string, unknown>,\n ): Promise<AuthResult<{ id: string; profile: Record<string, unknown> | null }>> {\n try {\n const response = await this.http.patch<{\n id: string;\n profile: Record<string, unknown> | null;\n }>('/api/auth/profiles/current', { profile });\n return { data: response, error: null };\n } catch (error) {\n return wrapError<{ id: string; profile: Record<string, unknown> | null }>(\n error,\n 'Failed to update profile',\n );\n }\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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACwGO,IAAM,kBAAN,MAAM,yBAAwB,MAAM;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EAEP,YACE,SACA,YACA,OACA,aACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,QAAQ;AACb,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,OAAO,aAAa,UAAqC;AACvD,WAAO,IAAI;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,EACF;AACF;;;ACxHA,IAAM,oBAAoB,CAAC,iBAAiB,aAAa,UAAU,YAAY;AAE/E,IAAM,sBAAsB;AAAA,EAC1B;AAAA,EAAY;AAAA,EAAS;AAAA,EAAe;AAAA,EACpC;AAAA,EAAiB;AAAA,EAAU;AAAA,EAAU;AAAA,EACrC;AAAA,EAAS;AAAA,EAAO;AAAA,EAAc;AAChC;AAEA,SAAS,cAAc,SAAyD;AAC9E,QAAM,WAAmC,CAAC;AAC1C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,QAAI,kBAAkB,SAAS,IAAI,YAAY,CAAC,GAAG;AACjD,eAAS,GAAG,IAAI;AAAA,IAClB,OAAO;AACL,eAAS,GAAG,IAAI;AAAA,IAClB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,MAAgB;AACpC,MAAI,SAAS,QAAQ,SAAS,OAAW,QAAO;AAChD,MAAI,OAAO,SAAS,UAAU;AAC5B,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,aAAO,aAAa,MAAM;AAAA,IAC5B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,MAAI,MAAM,QAAQ,IAAI,EAAG,QAAO,KAAK,IAAI,YAAY;AACrD,MAAI,OAAO,SAAS,UAAU;AAC5B,UAAM,YAAiC,CAAC;AACxC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,UAAI,oBAAoB,SAAS,IAAI,YAAY,EAAE,QAAQ,SAAS,EAAE,CAAC,GAAG;AACxE,kBAAU,GAAG,IAAI;AAAA,MACnB,OAAO;AACL,kBAAU,GAAG,IAAI,aAAa,KAAK;AAAA,MACrC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,WAAW,MAAmB;AACrC,MAAI,SAAS,UAAa,SAAS,KAAM,QAAO;AAChD,MAAI,OAAO,SAAS,UAAU;AAC5B,QAAI;AACF,aAAO,KAAK,UAAU,KAAK,MAAM,IAAI,GAAG,MAAM,CAAC;AAAA,IACjD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,MAAI,OAAO,aAAa,eAAe,gBAAgB,UAAU;AAC/D,WAAO;AAAA,EACT;AACA,MAAI;AACF,WAAO,KAAK,UAAU,MAAM,MAAM,CAAC;AAAA,EACrC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,IAAM,SAAN,MAAa;AAAA,EACX;AAAA,EACC;AAAA,EAER,YAAY,OAA+B;AACzC,QAAI,OAAO,UAAU,YAAY;AAC/B,WAAK,UAAU;AACf,WAAK,YAAY;AAAA,IACnB,OAAO;AACL,WAAK,UAAU,CAAC,CAAC;AACjB,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,IAAI,YAAoB,MAAmB;AACzC,QAAI,CAAC,KAAK,QAAS;AACnB,UAAM,YAAY,uBAAuB,OAAO;AAChD,QAAI,KAAK,WAAW;AAClB,WAAK,UAAU,WAAW,GAAG,IAAI;AAAA,IACnC,OAAO;AACL,cAAQ,IAAI,WAAW,GAAG,IAAI;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,KAAK,YAAoB,MAAmB;AAC1C,QAAI,CAAC,KAAK,QAAS;AACnB,UAAM,YAAY,uBAAuB,OAAO;AAChD,QAAI,KAAK,WAAW;AAClB,WAAK,UAAU,WAAW,GAAG,IAAI;AAAA,IACnC,OAAO;AACL,cAAQ,KAAK,WAAW,GAAG,IAAI;AAAA,IACjC;AAAA,EACF;AAAA,EAEA,MAAM,YAAoB,MAAmB;AAC3C,QAAI,CAAC,KAAK,QAAS;AACnB,UAAM,YAAY,uBAAuB,OAAO;AAChD,QAAI,KAAK,WAAW;AAClB,WAAK,UAAU,WAAW,GAAG,IAAI;AAAA,IACnC,OAAO;AACL,cAAQ,MAAM,WAAW,GAAG,IAAI;AAAA,IAClC;AAAA,EACF;AAAA,EAEA,WACE,QACA,KACA,SACA,MACM;AACN,QAAI,CAAC,KAAK,QAAS;AACnB,UAAM,QAAkB,CAAC,UAAK,MAAM,IAAI,GAAG,EAAE;AAC7C,QAAI,WAAW,OAAO,KAAK,OAAO,EAAE,SAAS,GAAG;AAC9C,YAAM,KAAK,cAAc,KAAK,UAAU,cAAc,OAAO,CAAC,CAAC,EAAE;AAAA,IACnE;AACA,UAAM,gBAAgB,WAAW,aAAa,IAAI,CAAC;AACnD,QAAI,eAAe;AACjB,YAAM,YAAY,cAAc,SAAS,MACrC,cAAc,MAAM,GAAG,GAAI,IAAI,oBAC/B;AACJ,YAAM,KAAK,WAAW,SAAS,EAAE;AAAA,IACnC;AACA,SAAK,IAAI,MAAM,KAAK,IAAI,CAAC;AAAA,EAC3B;AAAA,EAEA,YACE,QACA,KACA,QACA,YACA,MACM;AACN,QAAI,CAAC,KAAK,QAAS;AACnB,UAAM,QAAkB;AAAA,MACtB,UAAK,MAAM,IAAI,GAAG,IAAI,MAAM,KAAK,UAAU;AAAA,IAC7C;AACA,UAAM,gBAAgB,WAAW,aAAa,IAAI,CAAC;AACnD,QAAI,eAAe;AACjB,YAAM,YAAY,cAAc,SAAS,MACrC,cAAc,MAAM,GAAG,GAAI,IAAI,oBAC/B;AACJ,YAAM,KAAK,WAAW,SAAS,EAAE;AAAA,IACnC;AACA,QAAI,UAAU,KAAK;AACjB,WAAK,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,IAC7B,OAAO;AACL,WAAK,IAAI,MAAM,KAAK,IAAI,CAAC;AAAA,IAC3B;AAAA,EACF;AACF;;;ACzJO,IAAM,oBAAoB;AAE1B,SAAS,eAA8B;AAC5C,MAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,QAAM,QAAQ,SAAS,OACpB,MAAM,GAAG,EACT,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,iBAAiB,GAAG,CAAC;AAC3D,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK;AAChC;AAEO,SAAS,aAAa,OAAqB;AAChD,MAAI,OAAO,aAAa,YAAa;AACrC,QAAM,SAAS,IAAI,KAAK,KAAK;AAC7B,QAAM,SACJ,OAAO,WAAW,eAAe,OAAO,SAAS,aAAa,WAC1D,aACA;AACN,WAAS,SAAS,GAAG,iBAAiB,IAAI,mBAAmB,KAAK,CAAC,qBAAqB,MAAM,iBAAiB,MAAM;AACvH;AAEO,SAAS,iBAAuB;AACrC,MAAI,OAAO,aAAa,YAAa;AACrC,QAAM,SACJ,OAAO,WAAW,eAAe,OAAO,SAAS,aAAa,WAC1D,aACA;AACN,WAAS,SAAS,GAAG,iBAAiB,qCAAqC,MAAM;AACnF;AAEO,IAAM,eAAN,MAAmB;AAAA,EAChB,cAA6B;AAAA,EAC7B,OAAoB;AAAA;AAAA,EAG5B,gBAAqC;AAAA,EAErC,YAAY,SAA4B;AACtC,UAAM,eAAe,QAAQ,gBAAgB,KAAK;AAClD,SAAK,cAAc,QAAQ;AAC3B,SAAK,OAAO,QAAQ;AACpB,QAAI,gBAAgB,KAAK,eAAe;AACtC,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,aAAiC;AAC/B,QAAI,CAAC,KAAK,eAAe,CAAC,KAAK,KAAM,QAAO;AAC5C,WAAO;AAAA,MACL,aAAa,KAAK;AAAA,MAClB,MAAM,KAAK;AAAA,IACb;AAAA,EACF;AAAA,EAEA,iBAAgC;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,eAAe,OAAqB;AAClC,UAAM,eAAe,UAAU,KAAK;AACpC,SAAK,cAAc;AACnB,QAAI,gBAAgB,KAAK,eAAe;AACtC,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,UAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,QAAQ,MAAkB;AACxB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,eAAqB;AACnB,UAAM,WAAW,KAAK,gBAAgB;AACtC,SAAK,cAAc;AACnB,SAAK,OAAO;AACZ,QAAI,YAAY,KAAK,eAAe;AAClC,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AACF;;;ACzDA,IAAM,yBAAyB,oBAAI,IAAI,CAAC,KAAK,KAAK,KAAK,GAAG,CAAC;AAC3D,IAAM,qBAAqB,oBAAI,IAAI,CAAC,OAAO,QAAQ,OAAO,UAAU,SAAS,CAAC;AAEvE,IAAM,aAAN,MAAiB;AAAA,EACN;AAAA,EACA;AAAA,EACR;AAAA,EACA;AAAA,EACA,YAA2B;AAAA,EAC3B;AAAA,EACA,mBAA4B;AAAA,EAC5B,eAAwB;AAAA,EACxB,iBAAsD;AAAA,EACtD;AAAA,EACA,eAA8B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EAER,YACE,QACA,cACA,QACA;AACA,SAAK,UAAU,OAAO,WAAW;AACjC,SAAK,mBAAmB,OAAO,oBAAoB;AACnD,SAAK,QACH,OAAO,UACN,WAAW,QACR,WAAW,MAAM,KAAK,UAAU,IAC/B;AACP,SAAK,UAAU,OAAO;AACtB,SAAK,iBAAiB;AAAA,MACpB,GAAG,OAAO;AAAA,IACZ;AACA,SAAK,eAAe,gBAAgB,IAAI,aAAa;AACrD,SAAK,SAAS,UAAU,IAAI,OAAO,KAAK;AACxC,SAAK,UAAU,OAAO,WAAW;AACjC,SAAK,aAAa,OAAO,cAAc;AACvC,SAAK,aAAa,OAAO,cAAc;AAEvC,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,SAAS,MAAc,QAAyC;AACtE,UAAM,MAAM,IAAI,IAAI,MAAM,KAAK,OAAO;AACtC,QAAI,QAAQ;AACV,aAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAC/C,YAAI,QAAQ,UAAU;AAEpB,cAAI,kBAAkB,MAAM,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACtD,4BAAkB,gBACf,QAAQ,aAAa,GAAG,EACxB,QAAQ,aAAa,GAAG,EACxB,QAAQ,UAAU,GAAG,EACrB,QAAQ,UAAU,GAAG,EACrB,QAAQ,qBAAqB,GAAG;AACnC,cAAI,aAAa,OAAO,KAAK,eAAe;AAAA,QAC9C,OAAO;AACL,cAAI,aAAa,OAAO,KAAK,KAAK;AAAA,QACpC;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA,EAEQ,kBAAkB,QAAyB;AACjD,WAAO,uBAAuB,IAAI,MAAM;AAAA,EAC1C;AAAA,EAEQ,kBAAkB,SAAyB;AACjD,UAAM,OAAO,KAAK,aAAa,KAAK,IAAI,GAAG,UAAU,CAAC;AACtD,UAAM,SAAS,QAAQ,OAAO,KAAK,OAAO,IAAI;AAC9C,WAAO,KAAK,MAAM,MAAM;AAAA,EAC1B;AAAA,EAEA,MAAc,cACZ,QACA,MACA,UAA0B,CAAC,GACf;AACZ,UAAM;AAAA,MACJ;AAAA,MACA,UAAU,CAAC;AAAA,MACX;AAAA,MACA,QAAQ;AAAA,MACR,GAAG;AAAA,IACL,IAAI;AAEJ,UAAM,MAAM,KAAK,SAAS,MAAM,MAAM;AACtC,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,WACJ,mBAAmB,IAAI,OAAO,YAAY,CAAC,KAC3C,QAAQ,eAAe;AACzB,UAAM,cAAc,WAAW,KAAK,aAAa;AAEjD,UAAM,iBAAyC;AAAA,MAC7C,GAAG,KAAK;AAAA,IACV;AAEA,UAAM,YAAY,KAAK,aAAa,KAAK;AACzC,QAAI,WAAW;AACb,qBAAe,eAAe,IAAI,UAAU,SAAS;AAAA,IACvD;AAEA,QAAI;AACJ,QAAI,SAAS,QAAW;AACtB,UAAI,OAAO,aAAa,eAAe,gBAAgB,UAAU;AAC/D,wBAAgB;AAAA,MAClB,OAAO;AACL,YAAI,WAAW,OAAO;AACpB,yBAAe,cAAc,IAAI;AAAA,QACnC;AACA,wBAAgB,KAAK,UAAU,IAAI;AAAA,MACrC;AAAA,IACF;AAEA,QAAI,mBAAmB,SAAS;AAC9B,cAAQ,QAAQ,CAAC,OAAO,QAAQ;AAC9B,uBAAe,GAAG,IAAI;AAAA,MACxB,CAAC;AAAA,IACH,WAAW,MAAM,QAAQ,OAAO,GAAG;AACjC,cAAQ,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAChC,uBAAe,GAAG,IAAI;AAAA,MACxB,CAAC;AAAA,IACH,OAAO;AACL,aAAO,OAAO,gBAAgB,OAAO;AAAA,IACvC;AAEA,SAAK,OAAO,WAAW,QAAQ,KAAK,gBAAgB,aAAa;AAEjE,QAAI;AAEJ,aAAS,UAAU,GAAG,WAAW,aAAa,WAAW;AACvD,UAAI,UAAU,GAAG;AACf,cAAM,QAAQ,KAAK,kBAAkB,OAAO;AAC5C,aAAK,OAAO;AAAA,UACV,SAAS,OAAO,IAAI,WAAW,QAAQ,MAAM,IAAI,GAAG,OAAO,KAAK;AAAA,QAClE;AACA,YAAI,cAAc,QAAS,OAAM,aAAa;AAC9C,cAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,gBAAM,UAAU,MAAM;AACpB,yBAAaA,MAAK;AAClB,mBAAO,aAAc,MAAM;AAAA,UAC7B;AACA,gBAAMA,SAAQ,WAAW,MAAM;AAC7B,gBAAI;AACF,2BAAa,oBAAoB,SAAS,OAAO;AACnD,oBAAQ;AAAA,UACV,GAAG,KAAK;AACR,cAAI,cAAc;AAChB,yBAAa,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,UAChE;AAAA,QACF,CAAC;AAAA,MACH;AAEA,UAAI;AACJ,UAAI;AAEJ,UAAI,KAAK,UAAU,KAAK,cAAc;AACpC,qBAAa,IAAI,gBAAgB;AAEjC,YAAI,KAAK,UAAU,GAAG;AACpB,kBAAQ,WAAW,MAAM,WAAY,MAAM,GAAG,KAAK,OAAO;AAAA,QAC5D;AAEA,YAAI,cAAc;AAChB,cAAI,aAAa,SAAS;AACxB,uBAAW,MAAM,aAAa,MAAM;AAAA,UACtC,OAAO;AACL,kBAAM,gBAAgB,MAAM,WAAY,MAAM,aAAc,MAAM;AAClE,yBAAa,iBAAiB,SAAS,eAAe,EAAE,MAAM,KAAK,CAAC;AACpE,uBAAW,OAAO;AAAA,cAChB;AAAA,cACA,MAAM;AACJ,6BAAc,oBAAoB,SAAS,aAAa;AAAA,cAC1D;AAAA,cACA,EAAE,MAAM,KAAK;AAAA,YACf;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,MAAM,KAAK;AAAA,UACrC;AAAA,UACA,SAAS;AAAA,UACT,MAAM;AAAA,UACN,GAAG;AAAA,UACH,GAAI,aAAa,EAAE,QAAQ,WAAW,OAAO,IAAI,CAAC;AAAA,QACpD,CAAC;AAED,YAAI,KAAK,kBAAkB,SAAS,MAAM,KAAK,UAAU,aAAa;AACpE,cAAI,UAAU,OAAW,cAAa,KAAK;AAC3C,gBAAM,SAAS,MAAM,OAAO;AAC5B,sBAAY,IAAI;AAAA,YACd,iBAAiB,SAAS,MAAM,IAAI,SAAS,UAAU;AAAA,YACvD,SAAS;AAAA,YACT;AAAA,UACF;AACA;AAAA,QACF;AAEA,YAAI,SAAS,WAAW,KAAK;AAC3B,cAAI,UAAU,OAAW,cAAa,KAAK;AAC3C,iBAAO;AAAA,QACT;AAEA,YAAI;AACJ,cAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;AACvD,YAAI;AACF,cAAI,aAAa,SAAS,MAAM,GAAG;AACjC,mBAAO,MAAM,SAAS,KAAK;AAAA,UAC7B,OAAO;AACL,mBAAO,MAAM,SAAS,KAAK;AAAA,UAC7B;AAAA,QACF,SAAS,UAAe;AACtB,cAAI,UAAU,OAAW,cAAa,KAAK;AAC3C,gBAAM,IAAI;AAAA,YACR,kCAAkC,UAAU,WAAW,eAAe;AAAA,YACtE,SAAS;AAAA,YACT,SAAS,KAAK,gBAAgB;AAAA,UAChC;AAAA,QACF;AAEA,YAAI,UAAU,OAAW,cAAa,KAAK;AAE3C,YAAI,CAAC,SAAS,IAAI;AAChB,eAAK,OAAO;AAAA,YACV;AAAA,YACA;AAAA,YACA,SAAS;AAAA,YACT,KAAK,IAAI,IAAI;AAAA,YACb;AAAA,UACF;AACA,cAAI,QAAQ,OAAO,SAAS,YAAY,WAAW,MAAM;AACvD,gBAAI,CAAC,KAAK,cAAc,CAAC,KAAK,QAAQ;AACpC,mBAAK,aAAa,SAAS;AAAA,YAC7B;AACA,kBAAM,QAAQ,gBAAgB,aAAa,IAAgB;AAC3D,mBAAO,KAAK,IAAI,EAAE,QAAQ,CAAC,QAAQ;AACjC,kBAAI,QAAQ,WAAW,QAAQ,aAAa,QAAQ,cAAc;AAChE,gBAAC,MAAc,GAAG,IAAI,KAAK,GAAG;AAAA,cAChC;AAAA,YACF,CAAC;AACD,kBAAM;AAAA,UACR;AACA,gBAAM,IAAI;AAAA,YACR,mBAAmB,SAAS,UAAU;AAAA,YACtC,SAAS;AAAA,YACT;AAAA,UACF;AAAA,QACF;AAEA,aAAK,OAAO;AAAA,UACV;AAAA,UACA;AAAA,UACA,SAAS;AAAA,UACT,KAAK,IAAI,IAAI;AAAA,UACb;AAAA,QACF;AACA,eAAO;AAAA,MACT,SAAS,KAAU;AACjB,YAAI,UAAU,OAAW,cAAa,KAAK;AAE3C,YAAI,KAAK,SAAS,cAAc;AAC9B,cACE,cACA,WAAW,OAAO,WAClB,KAAK,UAAU,KACf,CAAC,cAAc,SACf;AACA,kBAAM,IAAI;AAAA,cACR,2BAA2B,KAAK,OAAO;AAAA,cACvC;AAAA,cACA;AAAA,YACF;AAAA,UACF;AACA,gBAAM;AAAA,QACR;AAEA,YAAI,eAAe,iBAAiB;AAClC,gBAAM;AAAA,QACR;AAEA,YAAI,UAAU,aAAa;AACzB,sBAAY;AACZ;AAAA,QACF;AAEA,cAAM,IAAI;AAAA,UACR,2BAA2B,KAAK,WAAW,eAAe;AAAA,UAC1D;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UACE,aACA,IAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EAEJ;AAAA,EAEA,MAAM,QACJ,QACA,MACA,UAA0B,CAAC,GACf;AACZ,QAAI;AACF,aAAO,MAAM,KAAK,cAAiB,QAAQ,MAAM,EAAE,GAAG,QAAQ,CAAC;AAAA,IACjE,SAAS,OAAO;AACd,UACE,iBAAiB,mBACjB,MAAM,eAAe,OACrB,MAAM,UAAU,mBAChB,KAAK,kBACL;AACA,YAAI;AACF,gBAAM,eAAe,MAAM,KAAK,mBAAmB;AACnD,eAAK,aAAa,aAAa,WAAW;AAC1C,eAAK,aAAc,YAAY,YAAY;AAC3C,cAAI,aAAa,WAAW;AAC1B,yBAAa,aAAa,SAAS;AAAA,UACrC;AACA,cAAI,aAAa,cAAc;AAC7B,iBAAK,gBAAgB,aAAa,YAAY;AAAA,UAChD;AACA,iBAAO,MAAM,KAAK,cAAiB,QAAQ,MAAM,EAAE,GAAG,QAAQ,CAAC;AAAA,QACjE,SAAS,cAAc;AACrB,eAAK,aAAa,aAAa;AAC/B,eAAK,YAAY;AACjB,eAAK,eAAe;AACpB,yBAAe;AACf,gBAAM;AAAA,QACR;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,IAAO,MAAc,SAAsC;AACzD,WAAO,KAAK,QAAW,OAAO,MAAM,OAAO;AAAA,EAC7C;AAAA,EAEA,KAAQ,MAAc,MAAY,SAAsC;AACtE,WAAO,KAAK,QAAW,QAAQ,MAAM,EAAE,GAAG,SAAS,KAAK,CAAC;AAAA,EAC3D;AAAA,EAEA,IAAO,MAAc,MAAY,SAAsC;AACrE,WAAO,KAAK,QAAW,OAAO,MAAM,EAAE,GAAG,SAAS,KAAK,CAAC;AAAA,EAC1D;AAAA,EAEA,MAAS,MAAc,MAAY,SAAsC;AACvE,WAAO,KAAK,QAAW,SAAS,MAAM,EAAE,GAAG,SAAS,KAAK,CAAC;AAAA,EAC5D;AAAA,EAEA,OAAU,MAAc,SAAsC;AAC5D,WAAO,KAAK,QAAW,UAAU,MAAM,OAAO;AAAA,EAChD;AAAA,EAEA,aAAa,OAAsB;AACjC,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,gBAAgB,OAAsB;AACpC,SAAK,eAAe;AAAA,EACtB;AAAA,EAEA,aAAqC;AACnC,UAAM,UAAU,EAAE,GAAG,KAAK,eAAe;AACzC,UAAM,YAAY,KAAK,aAAa,KAAK;AACzC,QAAI,WAAW;AACb,cAAQ,eAAe,IAAI,UAAU,SAAS;AAAA,IAChD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,qBAAmD;AACvD,QAAI,KAAK,cAAc;AACrB,aAAO,KAAK;AAAA,IACd;AAEA,SAAK,eAAe;AACpB,SAAK,kBAAkB,YAAY;AACjC,UAAI;AACF,cAAM,YAAY,aAAa;AAC/B,cAAM,OAAO,KAAK,eACd,EAAE,cAAc,KAAK,aAAa,IAClC;AACJ,cAAM,WAAW,MAAM,KAAK;AAAA,UAC1B;AAAA,UACA;AAAA,UACA;AAAA,YACE;AAAA,YACA,SAAS,YAAY,EAAE,gBAAgB,UAAU,IAAI,CAAC;AAAA,YACtD,aAAa;AAAA,UACf;AAAA,QACF;AACA,eAAO;AAAA,MACT,UAAE;AACA,aAAK,eAAe;AACpB,aAAK,iBAAiB;AAAA,MACxB;AAAA,IACF,GAAG;AAEH,WAAO,KAAK;AAAA,EACd;AACF;;;ACtZA,SAAS,UAAa,OAAgB,iBAAwC;AAC5E,MAAI,iBAAiB,iBAAiB;AACpC,WAAO,EAAE,MAAM,MAAM,MAAM;AAAA,EAC7B;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO,IAAI;AAAA,MACT,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MACzC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,OAAN,MAAW;AAAA,EAChB,YACU,MACA,cACR;AAFQ;AACA;AAAA,EACP;AAAA,EAFO;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOF,wBAAwB,UAA8B;AAC5D,UAAM,UAAuB;AAAA,MAC3B,aAAa,SAAS;AAAA,MACtB,MAAM,SAAS;AAAA,IACjB;AACA,QAAI,SAAS,WAAW;AACtB,mBAAa,SAAS,SAAS;AAAA,IACjC;AACA,SAAK,aAAa,YAAY,OAAO;AACrC,SAAK,KAAK,aAAa,SAAS,WAAW;AAC3C,SAAK,KAAK,gBAAgB,SAAS,gBAAgB,IAAI;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,OAAO,SAA2D;AACtE,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,KAAK;AAAA,QAC/B;AAAA,QACA;AAAA,QACA,EAAE,aAAa,UAAU;AAAA,MAC3B;AACA,UAAI,UAAU,eAAe,SAAS,MAAM;AAC1C,aAAK,wBAAwB,QAAQ;AAAA,MACvC;AACA,aAAO,EAAE,MAAM,UAAU,OAAO,KAAK;AAAA,IACvC,SAAS,OAAO;AACd,aAAO,UAAwB,OAAO,gBAAgB;AAAA,IACxD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBACJ,SACmC;AACnC,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,KAAK;AAAA,QAC/B;AAAA,QACA;AAAA,QACA,EAAE,aAAa,UAAU;AAAA,MAC3B;AACA,UAAI,UAAU,eAAe,SAAS,MAAM;AAC1C,aAAK,wBAAwB,QAAQ;AAAA,MACvC;AACA,aAAO,EAAE,MAAM,UAAU,OAAO,KAAK;AAAA,IACvC,SAAS,OAAO;AACd,aAAO,UAAwB,OAAO,gBAAgB;AAAA,IACxD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAsD;AAC1D,QAAI;AACF,UAAI;AACF,cAAM,KAAK,KAAK,KAAK,oBAAoB,QAAW;AAAA,UAClD,aAAa;AAAA,QACf,CAAC;AAAA,MACH,QAAQ;AAAA,MAER;AACA,WAAK,aAAa,aAAa;AAC/B,WAAK,KAAK,aAAa,IAAI;AAC3B,WAAK,KAAK,gBAAgB,IAAI;AAC9B,qBAAe;AACf,aAAO,EAAE,OAAO,KAAK;AAAA,IACvB,QAAQ;AACN,aAAO;AAAA,QACL,OAAO,IAAI,gBAAgB,sBAAsB,KAAK,eAAe;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,iBAAoD;AACxD,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,KAAK,mBAAmB;AACpD,UAAI,UAAU,eAAe,SAAS,MAAM;AAC1C,aAAK,wBAAwB,QAAQ;AAAA,MACvC;AACA,aAAO,EAAE,MAAM,UAAU,OAAO,KAAK;AAAA,IACvC,SAAS,OAAO;AACd,aAAO,UAAwB,OAAO,wBAAwB;AAAA,IAChE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAiC;AAC/B,WAAO,KAAK,aAAa,WAAW;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,UAAuB;AACrB,WAAO,KAAK,aAAa,QAAQ;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,iBAAsD;AAC1D,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,KAAK;AAAA,QAC/B;AAAA,MACF;AACA,UAAI,UAAU,MAAM;AAClB,cAAM,UAAuB;AAAA,UAC3B,aAAa,KAAK,aAAa,WAAW,GAAG,eAAe;AAAA,UAC5D,MAAM,SAAS;AAAA,QACjB;AACA,aAAK,aAAa,YAAY,OAAO;AAAA,MACvC;AACA,aAAO,EAAE,MAAM,UAAU,OAAO,KAAK;AAAA,IACvC,SAAS,OAAO;AACd,aAAO,UAA0B,OAAO,4BAA4B;AAAA,IACtE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WACJ,QAC8E;AAC9E,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,KAAK,IAG9B,sBAAsB,mBAAmB,MAAM,CAAC,EAAE;AACrD,aAAO,EAAE,MAAM,UAAU,OAAO,KAAK;AAAA,IACvC,SAAS,OAAO;AACd,aAAO;AAAA,QACL;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WACJ,SAC8E;AAC9E,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,KAAK,MAG9B,8BAA8B,EAAE,QAAQ,CAAC;AAC5C,aAAO,EAAE,MAAM,UAAU,OAAO,KAAK;AAAA,IACvC,SAAS,OAAO;AACd,aAAO;AAAA,QACL;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACpOA,0BAAgC;AAchC,SAAS,sBACP,YACA,cACA,SACc;AACd,SAAO,OAAO,OAA0B,SAA0C;AAChF,UAAM,MAAM,OAAO,UAAU,WAAW,QAAQ,MAAM,SAAS;AAC/D,UAAM,SAAS,IAAI,IAAI,GAAG;AAM1B,UAAM,WAAW,OAAO,SAAS,WAAW,GAAG,IAAI,OAAO,SAAS,MAAM,CAAC,IAAI,OAAO;AACrF,UAAM,WAAW,SAAS,MAAM,aAAa;AAC7C,UAAM,WAAW,WACb,qBAAqB,SAAS,CAAC,CAAC,KAChC,yBAAyB,QAAQ;AAErC,UAAM,YAAY,GAAG,WAAW,OAAO,GAAG,QAAQ,GAAG,OAAO,MAAM;AAIlE,UAAM,UAAU,IAAI,QAAQ,MAAM,OAAO;AACzC,QAAI,CAAC,QAAQ,IAAI,eAAe,GAAG;AACjC,YAAM,QAAQ,aAAa,eAAe,KAAK;AAC/C,UAAI,OAAO;AACT,gBAAQ,IAAI,iBAAiB,UAAU,KAAK,EAAE;AAAA,MAChD;AAAA,IACF;AAEA,WAAO,MAAM,WAAW,EAAE,GAAG,MAAM,QAAQ,CAAC;AAAA,EAC9C;AACF;AAEO,IAAM,WAAN,MAAe;AAAA,EACZ;AAAA,EACA;AAAA,EAER,YACE,YACA,cACA,SACA;AACA,SAAK,aAAa;AAKlB,SAAK,YAAY,IAAI,oCAA+B,gBAAgB;AAAA,MAClE,OAAO,sBAAsB,YAAY,cAAc,OAAO;AAAA,MAC9D,SAAS,CAAC;AAAA,IACZ,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,KAAK,OAAe;AAClB,QAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK,UAAU,KAAK,KAAK;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,IACE,IACA,MACA,SACA;AACA,WAAO,KAAK,UAAU,IAAI,IAAI,MAAM,OAAO;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAiB;AACf,WAAO,KAAK,WAAW;AAAA,EACzB;AACF;;;AChHO,IAAM,mBAAN,MAAuB;AAAA,EACpB;AAAA,EACA;AAAA,EACQ;AAAA,EACA;AAAA,EAEhB,YAAY,SAA2B,CAAC,GAAG;AACzC,UAAM,SAAS,IAAI,OAAO,OAAO,KAAK;AACtC,SAAK,eAAe,IAAI,aAAa;AACrC,SAAK,OAAO,IAAI,WAAW,QAAQ,KAAK,cAAc,MAAM;AAC5D,SAAK,OAAO,IAAI,KAAK,KAAK,MAAM,KAAK,YAAY;AACjD,SAAK,WAAW,IAAI,SAAS,KAAK,MAAM,KAAK,cAAc,OAAO,OAAO;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAA4B;AAC1B,WAAO,KAAK;AAAA,EACd;AACF;;;APpBO,SAAS,aAAa,QAA4C;AACvE,SAAO,IAAI,iBAAiB,MAAM;AACpC;AAGA,IAAO,gBAAQ;","names":["timer"]}
package/dist/index.d.cts CHANGED
@@ -16,8 +16,8 @@ import * as _supabase_postgrest_js from '@supabase/postgrest-js';
16
16
  interface User {
17
17
  id: string;
18
18
  email: string;
19
- /** Hashed password — usually omitted from API responses but included in the type for shape parity. */
20
- password: string | null;
19
+ /** Hashed password — omitted from most API responses (getCurrentUser, getProfile). Only present in register/login legacy responses. */
20
+ password?: string | null;
21
21
  is_project_admin: boolean;
22
22
  profile: Record<string, unknown>;
23
23
  metadata: Record<string, unknown>;
@@ -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
@@ -312,13 +310,34 @@ declare class Auth {
312
310
  * Get the current in-memory user, or null if not signed in.
313
311
  */
314
312
  getUser(): User | null;
313
+ /**
314
+ * Fetch the current user from the backend. Unlike getUser() which reads
315
+ * from memory, this makes a network request and returns the latest data.
316
+ */
317
+ getCurrentUser(): Promise<AuthResult<{
318
+ user: User;
319
+ }>>;
320
+ /**
321
+ * Get a user's profile by ID. Requires authentication.
322
+ */
323
+ getProfile(userId: string): Promise<AuthResult<{
324
+ id: string;
325
+ profile: Record<string, unknown> | null;
326
+ }>>;
327
+ /**
328
+ * Update the current user's profile. Merges with existing profile data —
329
+ * only the fields you pass are updated, existing fields are preserved.
330
+ */
331
+ setProfile(profile: Record<string, unknown>): Promise<AuthResult<{
332
+ id: string;
333
+ profile: Record<string, unknown> | null;
334
+ }>>;
315
335
  }
316
336
 
317
337
  declare class Database {
318
338
  private postgrest;
319
- private postgrestUrl;
320
- constructor(tokenManager: TokenManager, postgrestUrl: string | undefined, anonKey: string | undefined);
321
- private requireClient;
339
+ private httpClient;
340
+ constructor(httpClient: HttpClient, tokenManager: TokenManager, anonKey: string | undefined);
322
341
  /**
323
342
  * Build a PostgREST query against a table.
324
343
  *
@@ -351,10 +370,11 @@ declare class Database {
351
370
  count?: 'exact' | 'planned' | 'estimated';
352
371
  }): _supabase_postgrest_js.PostgrestFilterBuilder<any, any, any, any, string, null, "RPC">;
353
372
  /**
354
- * The PostgREST URL the database client is talking to, or undefined if
355
- * the database module is not configured.
373
+ * The backend base URL the database client is targeting. Useful for
374
+ * debugging — the actual PostgREST instance is internal and not
375
+ * reachable by the SDK directly.
356
376
  */
357
- getUrl(): string | undefined;
377
+ getUrl(): string;
358
378
  }
359
379
 
360
380
  /**
@@ -362,12 +382,11 @@ declare class Database {
362
382
  *
363
383
  * @example
364
384
  * ```typescript
365
- * import { createClient } from '@mitway-baas/sdk';
385
+ * import { createClient } from '@mitway/sdk';
366
386
  *
367
387
  * 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
388
+ * baseUrl: 'https://acme.api.dev.nttmitway.com',
389
+ * anonKey: 'eyJhbGciOiJIUzI1NiIs...', // optional
371
390
  * });
372
391
  *
373
392
  * // Auth
@@ -376,7 +395,8 @@ declare class Database {
376
395
  * password: 'pw',
377
396
  * });
378
397
  *
379
- * // Database
398
+ * // Database — transparently routed through the backend proxy at
399
+ * // /api/database/records/* (no separate PostgREST URL).
380
400
  * const { data, error: dbError } = await client.database
381
401
  * .from('posts')
382
402
  * .select('*')
package/dist/index.d.ts CHANGED
@@ -16,8 +16,8 @@ import * as _supabase_postgrest_js from '@supabase/postgrest-js';
16
16
  interface User {
17
17
  id: string;
18
18
  email: string;
19
- /** Hashed password — usually omitted from API responses but included in the type for shape parity. */
20
- password: string | null;
19
+ /** Hashed password — omitted from most API responses (getCurrentUser, getProfile). Only present in register/login legacy responses. */
20
+ password?: string | null;
21
21
  is_project_admin: boolean;
22
22
  profile: Record<string, unknown>;
23
23
  metadata: Record<string, unknown>;
@@ -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
@@ -312,13 +310,34 @@ declare class Auth {
312
310
  * Get the current in-memory user, or null if not signed in.
313
311
  */
314
312
  getUser(): User | null;
313
+ /**
314
+ * Fetch the current user from the backend. Unlike getUser() which reads
315
+ * from memory, this makes a network request and returns the latest data.
316
+ */
317
+ getCurrentUser(): Promise<AuthResult<{
318
+ user: User;
319
+ }>>;
320
+ /**
321
+ * Get a user's profile by ID. Requires authentication.
322
+ */
323
+ getProfile(userId: string): Promise<AuthResult<{
324
+ id: string;
325
+ profile: Record<string, unknown> | null;
326
+ }>>;
327
+ /**
328
+ * Update the current user's profile. Merges with existing profile data —
329
+ * only the fields you pass are updated, existing fields are preserved.
330
+ */
331
+ setProfile(profile: Record<string, unknown>): Promise<AuthResult<{
332
+ id: string;
333
+ profile: Record<string, unknown> | null;
334
+ }>>;
315
335
  }
316
336
 
317
337
  declare class Database {
318
338
  private postgrest;
319
- private postgrestUrl;
320
- constructor(tokenManager: TokenManager, postgrestUrl: string | undefined, anonKey: string | undefined);
321
- private requireClient;
339
+ private httpClient;
340
+ constructor(httpClient: HttpClient, tokenManager: TokenManager, anonKey: string | undefined);
322
341
  /**
323
342
  * Build a PostgREST query against a table.
324
343
  *
@@ -351,10 +370,11 @@ declare class Database {
351
370
  count?: 'exact' | 'planned' | 'estimated';
352
371
  }): _supabase_postgrest_js.PostgrestFilterBuilder<any, any, any, any, string, null, "RPC">;
353
372
  /**
354
- * The PostgREST URL the database client is talking to, or undefined if
355
- * the database module is not configured.
373
+ * The backend base URL the database client is targeting. Useful for
374
+ * debugging — the actual PostgREST instance is internal and not
375
+ * reachable by the SDK directly.
356
376
  */
357
- getUrl(): string | undefined;
377
+ getUrl(): string;
358
378
  }
359
379
 
360
380
  /**
@@ -362,12 +382,11 @@ declare class Database {
362
382
  *
363
383
  * @example
364
384
  * ```typescript
365
- * import { createClient } from '@mitway-baas/sdk';
385
+ * import { createClient } from '@mitway/sdk';
366
386
  *
367
387
  * 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
388
+ * baseUrl: 'https://acme.api.dev.nttmitway.com',
389
+ * anonKey: 'eyJhbGciOiJIUzI1NiIs...', // optional
371
390
  * });
372
391
  *
373
392
  * // Auth
@@ -376,7 +395,8 @@ declare class Database {
376
395
  * password: 'pw',
377
396
  * });
378
397
  *
379
- * // Database
398
+ * // Database — transparently routed through the backend proxy at
399
+ * // /api/database/records/* (no separate PostgREST URL).
380
400
  * const { data, error: dbError } = await client.database
381
401
  * .from('posts')
382
402
  * .select('*')
package/dist/index.js CHANGED
@@ -698,12 +698,68 @@ var Auth = class {
698
698
  getUser() {
699
699
  return this.tokenManager.getUser();
700
700
  }
701
+ /**
702
+ * Fetch the current user from the backend. Unlike getUser() which reads
703
+ * from memory, this makes a network request and returns the latest data.
704
+ */
705
+ async getCurrentUser() {
706
+ try {
707
+ const response = await this.http.get(
708
+ "/api/auth/sessions/current"
709
+ );
710
+ if (response?.user) {
711
+ const session = {
712
+ accessToken: this.tokenManager.getSession()?.accessToken ?? "",
713
+ user: response.user
714
+ };
715
+ this.tokenManager.saveSession(session);
716
+ }
717
+ return { data: response, error: null };
718
+ } catch (error) {
719
+ return wrapError(error, "Failed to get current user");
720
+ }
721
+ }
722
+ /**
723
+ * Get a user's profile by ID. Requires authentication.
724
+ */
725
+ async getProfile(userId) {
726
+ try {
727
+ const response = await this.http.get(`/api/auth/profiles/${encodeURIComponent(userId)}`);
728
+ return { data: response, error: null };
729
+ } catch (error) {
730
+ return wrapError(
731
+ error,
732
+ "Failed to get profile"
733
+ );
734
+ }
735
+ }
736
+ /**
737
+ * Update the current user's profile. Merges with existing profile data —
738
+ * only the fields you pass are updated, existing fields are preserved.
739
+ */
740
+ async setProfile(profile) {
741
+ try {
742
+ const response = await this.http.patch("/api/auth/profiles/current", { profile });
743
+ return { data: response, error: null };
744
+ } catch (error) {
745
+ return wrapError(
746
+ error,
747
+ "Failed to update profile"
748
+ );
749
+ }
750
+ }
701
751
  };
702
752
 
703
753
  // src/modules/database.ts
704
754
  import { PostgrestClient } from "@supabase/postgrest-js";
705
- function createAuthedFetch(tokenManager, anonKey) {
755
+ function createMitwayBaasFetch(httpClient, tokenManager, anonKey) {
706
756
  return async (input, init) => {
757
+ const url = typeof input === "string" ? input : input.toString();
758
+ const urlObj = new URL(url);
759
+ const pathname = urlObj.pathname.startsWith("/") ? urlObj.pathname.slice(1) : urlObj.pathname;
760
+ const rpcMatch = pathname.match(/^rpc\/(.+)$/);
761
+ const endpoint = rpcMatch ? `/api/database/rpc/${rpcMatch[1]}` : `/api/database/records/${pathname}`;
762
+ const targetUrl = `${httpClient.baseUrl}${endpoint}${urlObj.search}`;
707
763
  const headers = new Headers(init?.headers);
708
764
  if (!headers.has("Authorization")) {
709
765
  const token = tokenManager.getAccessToken() ?? anonKey;
@@ -711,32 +767,18 @@ function createAuthedFetch(tokenManager, anonKey) {
711
767
  headers.set("Authorization", `Bearer ${token}`);
712
768
  }
713
769
  }
714
- return fetch(input, { ...init, headers });
770
+ return fetch(targetUrl, { ...init, headers });
715
771
  };
716
772
  }
717
773
  var Database = class {
718
774
  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;
775
+ httpClient;
776
+ constructor(httpClient, tokenManager, anonKey) {
777
+ this.httpClient = httpClient;
778
+ this.postgrest = new PostgrestClient("http://dummy", {
779
+ fetch: createMitwayBaasFetch(httpClient, tokenManager, anonKey),
780
+ headers: {}
781
+ });
740
782
  }
741
783
  /**
742
784
  * Build a PostgREST query against a table.
@@ -757,7 +799,14 @@ var Database = class {
757
799
  * .single();
758
800
  */
759
801
  from(table) {
760
- return this.requireClient().from(table);
802
+ if (!table || typeof table !== "string") {
803
+ throw new MitwayBaasError(
804
+ "Database.from(table) requires a non-empty string",
805
+ 400,
806
+ "INVALID_TABLE_NAME"
807
+ );
808
+ }
809
+ return this.postgrest.from(table);
761
810
  }
762
811
  /**
763
812
  * Call a PostgreSQL stored function (RPC).
@@ -767,14 +816,15 @@ var Database = class {
767
816
  * .rpc('get_user_stats', { user_id: 123 });
768
817
  */
769
818
  rpc(fn, args, options) {
770
- return this.requireClient().rpc(fn, args, options);
819
+ return this.postgrest.rpc(fn, args, options);
771
820
  }
772
821
  /**
773
- * The PostgREST URL the database client is talking to, or undefined if
774
- * the database module is not configured.
822
+ * The backend base URL the database client is targeting. Useful for
823
+ * debugging — the actual PostgREST instance is internal and not
824
+ * reachable by the SDK directly.
775
825
  */
776
826
  getUrl() {
777
- return this.postgrestUrl;
827
+ return this.httpClient.baseUrl;
778
828
  }
779
829
  };
780
830
 
@@ -789,7 +839,7 @@ var MitwayBaasClient = class {
789
839
  this.tokenManager = new TokenManager();
790
840
  this.http = new HttpClient(config, this.tokenManager, logger);
791
841
  this.auth = new Auth(this.http, this.tokenManager);
792
- this.database = new Database(this.tokenManager, config.postgrestUrl, config.anonKey);
842
+ this.database = new Database(this.http, this.tokenManager, config.anonKey);
793
843
  }
794
844
  /**
795
845
  * 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 * Fetch the current user from the backend. Unlike getUser() which reads\n * from memory, this makes a network request and returns the latest data.\n */\n async getCurrentUser(): Promise<AuthResult<{ user: User }>> {\n try {\n const response = await this.http.get<{ user: User }>(\n '/api/auth/sessions/current',\n );\n if (response?.user) {\n const session: AuthSession = {\n accessToken: this.tokenManager.getSession()?.accessToken ?? '',\n user: response.user,\n };\n this.tokenManager.saveSession(session);\n }\n return { data: response, error: null };\n } catch (error) {\n return wrapError<{ user: User }>(error, 'Failed to get current user');\n }\n }\n\n /**\n * Get a user's profile by ID. Requires authentication.\n */\n async getProfile(\n userId: string,\n ): Promise<AuthResult<{ id: string; profile: Record<string, unknown> | null }>> {\n try {\n const response = await this.http.get<{\n id: string;\n profile: Record<string, unknown> | null;\n }>(`/api/auth/profiles/${encodeURIComponent(userId)}`);\n return { data: response, error: null };\n } catch (error) {\n return wrapError<{ id: string; profile: Record<string, unknown> | null }>(\n error,\n 'Failed to get profile',\n );\n }\n }\n\n /**\n * Update the current user's profile. Merges with existing profile data —\n * only the fields you pass are updated, existing fields are preserved.\n */\n async setProfile(\n profile: Record<string, unknown>,\n ): Promise<AuthResult<{ id: string; profile: Record<string, unknown> | null }>> {\n try {\n const response = await this.http.patch<{\n id: string;\n profile: Record<string, unknown> | null;\n }>('/api/auth/profiles/current', { profile });\n return { data: response, error: null };\n } catch (error) {\n return wrapError<{ id: string; profile: Record<string, unknown> | null }>(\n error,\n 'Failed to update profile',\n );\n }\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.1",
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",
@@ -40,7 +40,7 @@
40
40
  "license": "Apache-2.0",
41
41
  "repository": {
42
42
  "type": "git",
43
- "url": "https://github.com/INC-DataInnovation/MITWAY-Sdk.git"
43
+ "url": "git+https://github.com/INC-DataInnovation/MITWAY-Sdk.git"
44
44
  },
45
45
  "bugs": {
46
46
  "url": "https://github.com/INC-DataInnovation/MITWAY-Sdk/issues"