@mitway/sdk 0.5.0 → 0.7.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
@@ -1,29 +1,22 @@
1
1
  # @mitway/sdk
2
2
 
3
3
  TypeScript/JavaScript client for the **MITWAY-BaaS** backend. Lets end-user
4
- apps sign up, sign in, refresh tokens, and run PostgREST queries against a
5
- per-cliente MITWAY-BaaS deployment through a single public URL.
4
+ apps sign up, sign in, refresh tokens, run PostgREST queries, subscribe to
5
+ realtime events, and manage storage against a per-tenant MITWAY-BaaS deployment.
6
6
 
7
7
  ## Status
8
8
 
9
- **v0.2.0 — backend proxy.** Currently ships:
9
+ **v0.5.0**
10
10
 
11
11
  | Module | Status | Notes |
12
12
  |---|---|---|
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
- | `storage` | Not yet | Backend has no `/api/storage/*` 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
- | `email` | Not yet | Backend has no `/api/email/*` routes |
18
- | `ai` | Not yet | Backend has no `/api/ai/*` routes |
19
- | `realtime` | Not yet | No realtime subsystem |
20
-
21
- When the backend grows the missing routes, port the corresponding modules
22
- from upstream
23
- [`InsForge/InsForge-sdk-js`](https://github.com/InsForge/InsForge-sdk-js)
24
- (`src/modules/{storage,functions,email,ai,realtime}.ts`). The SDK was
25
- structured intentionally to match upstream so future ports are mechanical
26
- rebrands.
13
+ | `auth` | Working | `signUp`, `signInWithPassword`, `signOut`, `refreshSession`, `getSession`, `getUser`, `getCurrentUser`, `getProfile`, `setProfile`, `onAuthStateChange` |
14
+ | `database` | Working | PostgREST query builder via `@supabase/postgrest-js` |
15
+ | `realtime` | Working | Socket.IO transport with channels (postgres_changes, broadcast, presence) |
16
+ | `storage` | Working | Bucket admin + object operations (upload, download, signed URLs, public URLs) |
17
+ | `functions` | MCP only | Backend routes + MCP tools working. No SDK module |
18
+ | `email` | Not yet | Backend has no `/api/email/*` routes |
19
+ | `ai` | Not yet | Backend has no `/api/ai/*` routes |
27
20
 
28
21
  ## Install
29
22
 
@@ -37,8 +30,8 @@ pnpm add @mitway/sdk
37
30
  import { createClient } from '@mitway/sdk';
38
31
 
39
32
  const client = createClient({
40
- baseUrl: 'https://acme.api.dev.nttmitway.com', // single backend URL
41
- anonKey: 'eyJhbGciOiJIUzI1NiIs...', // optional; signed JWT with role=anon
33
+ baseUrl: 'https://acme.api.dev.nttmitway.com',
34
+ anonKey: 'eyJhbGciOiJIUzI1NiIs...',
42
35
  });
43
36
 
44
37
  // Sign up
@@ -89,6 +82,14 @@ const { data: pub } = client.storage
89
82
  .from('avatars')
90
83
  .getPublicUrl('user-123/avatar.png');
91
84
 
85
+ // Realtime subscription
86
+ const channel = client.realtime
87
+ .channel('posts-feed')
88
+ .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'posts' }, (payload) => {
89
+ console.log('New post:', payload);
90
+ })
91
+ .subscribe();
92
+
92
93
  // Sign out
93
94
  await client.auth.signOut();
94
95
  ```
@@ -106,17 +107,89 @@ interface MitwayBaasConfig {
106
107
  retryCount?: number; // default 3 (0 disables)
107
108
  retryDelay?: number; // default 500 ms (exponential backoff with jitter)
108
109
  autoRefreshToken?: boolean;// default true (refreshes on 401 INVALID_TOKEN)
110
+ persistSession?: boolean; // default true (session survives F5)
111
+ storageKey?: string; // default 'mitway_baas_session'
112
+ storage?: StorageAdapter; // default browser localStorage — pluggable
113
+ multiTab?: boolean; // default true (sync session across tabs via `storage` event)
114
+ realtime?: RealtimeOptions;
115
+ }
116
+
117
+ interface StorageAdapter {
118
+ getItem(key: string): string | null;
119
+ setItem(key: string, value: string): void;
120
+ removeItem(key: string): void;
109
121
  }
110
122
  ```
111
123
 
112
- `baseUrl` is the **only** URL consumers need. Auth, database, and (in the
113
- future) storage/functions all route through the same backend. PostgREST
114
- is an internal ClusterIP Pod per cliente and is never publicly exposed —
115
- the backend proxies database requests to it over the cluster network.
124
+ ### Reactive auth `onAuthStateChange`
116
125
 
117
- ## Auth flow
126
+ Subscribe to session transitions (sign-in, sign-out, token refresh,
127
+ cross-tab sync, profile update) without polling `getSession()`. Returns
128
+ a `Subscription`; call `.unsubscribe()` to stop.
129
+
130
+ ```typescript
131
+ const sub = client.auth.onAuthStateChange((event, session) => {
132
+ // event: 'INITIAL_SESSION' | 'SIGNED_IN' | 'SIGNED_OUT'
133
+ // | 'TOKEN_REFRESHED' | 'USER_UPDATED'
134
+ if (event === 'SIGNED_OUT') router.push('/login');
135
+ });
136
+
137
+ // later
138
+ sub.unsubscribe();
139
+ ```
140
+
141
+ ### Custom storage (e.g., cross-subdomain cookie)
142
+
143
+ Pass a `storage` adapter to back the session with something other than
144
+ the default `localStorage` — cookies, a native secure store, an
145
+ in-memory stub for tests. The adapter is called on every session
146
+ mutation (sign-in, refresh, logout), so anything layered on top of it
147
+ sees a complete session lifecycle.
148
+
149
+ ```typescript
150
+ import { createClient, createLocalStorageAdapter } from '@mitway/sdk';
151
+ import type { StorageAdapter } from '@mitway/sdk';
152
+
153
+ const localAdapter = createLocalStorageAdapter();
154
+
155
+ const dualStorage: StorageAdapter = {
156
+ getItem: (k) => localAdapter.getItem(k) ?? readFromCookie(k),
157
+ setItem: (k, v) => { localAdapter.setItem(k, v); writeCookie(k, v); },
158
+ removeItem: (k) => { localAdapter.removeItem(k); clearCookie(k); },
159
+ };
160
+
161
+ const client = createClient({
162
+ baseUrl: 'https://…',
163
+ storage: dualStorage,
164
+ });
165
+ ```
118
166
 
119
- The SDK targets the routes the MITWAY-BaaS backend currently exposes:
167
+ `baseUrl` is the **only** URL consumers need. Auth, database, storage, and realtime
168
+ all route through the same backend.
169
+
170
+ ## Releasing a new version
171
+
172
+ Releases are automated via GitHub Actions with OIDC provenance.
173
+
174
+ **Steps:**
175
+
176
+ 1. Bump the version in `package.json`:
177
+
178
+ ```bash
179
+ pnpm version patch # or minor / major
180
+ ```
181
+
182
+ 2. Push the commit and tag:
183
+
184
+ ```bash
185
+ git push --follow-tags
186
+ ```
187
+
188
+ 3. Create a **Release** on GitHub pointing to the new tag (e.g. `v0.5.1`).
189
+
190
+ The workflow (`.github/workflows/publish.yml`) triggers on the release event, runs `typecheck`, `test`, `build`, and publishes to npm with provenance attestation. Requires an `NPM_TOKEN` secret configured in the repository.
191
+
192
+ ## Auth flow
120
193
 
121
194
  | Method | Backend route |
122
195
  |---|---|
@@ -125,43 +198,22 @@ The SDK targets the routes the MITWAY-BaaS backend currently exposes:
125
198
  | `signOut()` | `POST /api/auth/logout` |
126
199
  | `refreshSession()` (also automatic on 401) | `POST /api/auth/refresh` |
127
200
 
128
- The InsForge SDK uses different paths (`/api/auth/users`, `/api/auth/sessions`,
129
- etc.); those are not implemented in MITWAY-BaaS.
130
-
131
201
  The `HttpClient` automatically calls `refreshSession()` and retries the
132
- original request when it receives a `401 INVALID_TOKEN` response, so you
133
- don't need to manage refresh manually.
202
+ original request when it receives a `401 INVALID_TOKEN` response.
134
203
 
135
204
  ## Database flow
136
205
 
137
206
  The `database` module is a thin wrapper around
138
- [`@supabase/postgrest-js`](https://github.com/supabase/postgrest-js)
139
- configured with a custom fetch that rewrites every outgoing URL:
140
-
141
- - `http://dummy/{table}?…` → `{baseUrl}/api/database/records/{table}?…`
142
- - `http://dummy/rpc/{fn}?…` → `{baseUrl}/api/database/rpc/{fn}?…`
143
-
144
- These paths hit the MITWAY-BaaS backend, which then proxies the request
145
- internally to the per-cliente PostgREST Pod (`mitway-baas-{client}-postgrest:3000`)
146
- over the cluster network. PostgREST verifies the JWT with the shared
147
- tenant `JWT_SECRET` and enforces RLS based on the role claim.
148
-
149
- The full
150
- [PostgREST query builder API](https://supabase.com/docs/reference/javascript/select)
151
- is available: `select`, `insert`, `update`, `upsert`, `delete`, `rpc`,
152
- filters (`.eq`, `.neq`, `.gt`, `.like`, `.in`, …), modifiers (`.order`,
153
- `.limit`, `.range`, `.single`, …), foreign-key joins
154
- (`select('*, author:users(*)')`).
207
+ [`@supabase/postgrest-js`](https://github.com/supabase/postgrest-js).
208
+ The full PostgREST query builder API is available: `select`, `insert`, `update`,
209
+ `upsert`, `delete`, `rpc`, filters, modifiers, and foreign-key joins.
155
210
 
156
- Authorization is read from the `TokenManager` on every request, so a
157
- sign-in/sign-out is picked up automatically — no need to recreate the client.
211
+ Authorization is read from the `TokenManager` on every request, so a sign-in/sign-out
212
+ is picked up automatically.
158
213
 
159
214
  ## Origin
160
215
 
161
216
  Forked structurally from
162
217
  [`InsForge/InsForge-sdk-js`](https://github.com/InsForge/InsForge-sdk-js).
163
218
  Kept the `lib/` infrastructure (http-client, token-manager, logger)
164
- almost verbatim with rebranding. Rewrote `auth` for the MITWAY-BaaS
165
- routes and `database` to use the same fetch-rewriting pattern as
166
- upstream — both hit a backend proxy that forwards to the internal
167
- PostgREST, collapsing the per-cliente public surface into a single URL.
219
+ with rebranding. Rewrote `auth` and `database` for the MITWAY-BaaS routes.