@techfinityedge/koolbase-react-native 2.4.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,9 +16,9 @@ Auth, database, storage, realtime, functions, feature flags, remote config, vers
16
16
  3. Add the SDK:
17
17
 
18
18
  ```bash
19
- npm install @techfinityedge/koolbase-react-native@^2.0.0
19
+ npm install @techfinityedge/koolbase-react-native@^3.0.0
20
20
  # or
21
- yarn add @techfinityedge/koolbase-react-native@^2.0.0
21
+ yarn add @techfinityedge/koolbase-react-native@^3.0.0
22
22
  ```
23
23
 
24
24
  **4. Initialize at app startup:**
@@ -36,6 +36,13 @@ That's it. Every feature below is now available via `Koolbase.*`.
36
36
 
37
37
  ---
38
38
 
39
+ > **Auth is automatic (v3+).** Database, storage, and functions calls
40
+ > authenticate as the currently signed-in user — nothing to pass, no manual
41
+ > wiring. Log in (or restore a session) and every request carries that
42
+ > identity. `owner`/`authenticated` collections require an active session.
43
+
44
+ ---
45
+
39
46
  ## Authentication
40
47
 
41
48
  Email + password, Apple Sign-In, Google Sign-In, and phone + OTP — out of the box.
package/dist/auth.d.ts CHANGED
@@ -132,6 +132,14 @@ export declare class KoolbaseAuth {
132
132
  unlock(token: string): Promise<void>;
133
133
  get currentUser(): KoolbaseUser | null;
134
134
  get accessToken(): string | null;
135
+ /**
136
+ * Currently-valid access token for data-plane requests, refreshing
137
+ * (via refresh()) if the cached one is near expiry. Returns null when no
138
+ * session exists or refresh fails — callers then go api-key-only and the
139
+ * server treats it as having no end-user identity. The db/storage/functions
140
+ * clients pull from this per request so identity follows the live session.
141
+ */
142
+ validAccessToken(): Promise<string | null>;
135
143
  setSession(session: KoolbaseSession | null): Promise<void>;
136
144
  /**
137
145
  * @deprecated v1.9.0: Server endpoint /v1/sdk/auth/oauth not yet
package/dist/auth.js CHANGED
@@ -497,6 +497,23 @@ class KoolbaseAuth {
497
497
  get accessToken() {
498
498
  return this.session?.accessToken ?? null;
499
499
  }
500
+ /**
501
+ * Currently-valid access token for data-plane requests, refreshing
502
+ * (via refresh()) if the cached one is near expiry. Returns null when no
503
+ * session exists or refresh fails — callers then go api-key-only and the
504
+ * server treats it as having no end-user identity. The db/storage/functions
505
+ * clients pull from this per request so identity follows the live session.
506
+ */
507
+ async validAccessToken() {
508
+ if (!this.session)
509
+ return null;
510
+ try {
511
+ return await this._ensureValidToken();
512
+ }
513
+ catch {
514
+ return null;
515
+ }
516
+ }
500
517
  async setSession(session) {
501
518
  if (session) {
502
519
  await this.setSessionInternal(session);
@@ -2,9 +2,10 @@ import { KoolbaseConfig, KoolbaseRecord, QueryOptions, QueryResult, UpsertResult
2
2
  export declare class KoolbaseDatabase {
3
3
  private config;
4
4
  private getUserId;
5
+ private getToken;
5
6
  private syncEngine;
6
- constructor(config: KoolbaseConfig, getUserId: () => string | null);
7
- private get headers();
7
+ constructor(config: KoolbaseConfig, getUserId: () => string | null, getToken: () => Promise<string | null>);
8
+ private buildHeaders;
8
9
  private request;
9
10
  private runQuery;
10
11
  query(collection: string, options?: QueryOptions): Promise<QueryResult>;
package/dist/database.js CHANGED
@@ -9,24 +9,27 @@ function generateId() {
9
9
  return 'local_' + Math.random().toString(36).slice(2) + Date.now().toString(36);
10
10
  }
11
11
  class KoolbaseDatabase {
12
- constructor(config, getUserId) {
12
+ constructor(config, getUserId, getToken) {
13
13
  this.config = config;
14
14
  this.getUserId = getUserId;
15
- this.syncEngine = new sync_engine_1.SyncEngine(config, getUserId);
15
+ this.getToken = getToken;
16
+ this.syncEngine = new sync_engine_1.SyncEngine(config, getUserId, getToken);
16
17
  this.syncEngine.start();
17
18
  }
18
- get headers() {
19
- const userId = this.getUserId();
19
+ // getUserId is kept only for local cache keys / offline metadata; request
20
+ // identity now comes solely from the verified access token.
21
+ async buildHeaders() {
22
+ const token = await this.getToken();
20
23
  return {
21
24
  'Content-Type': 'application/json',
22
25
  'x-api-key': this.config.publicKey,
23
- ...(userId ? { 'x-user-id': userId } : {}),
26
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
24
27
  };
25
28
  }
26
29
  async request(method, path, body) {
27
30
  const res = await fetch(`${this.config.baseUrl}${path}`, {
28
31
  method,
29
- headers: this.headers,
32
+ headers: await this.buildHeaders(),
30
33
  body: body ? JSON.stringify(body) : undefined,
31
34
  });
32
35
  const data = await res.json();
@@ -117,7 +120,7 @@ class KoolbaseDatabase {
117
120
  async upsert(collection, match, data) {
118
121
  const res = await fetch(`${this.config.baseUrl}/v1/sdk/db/upsert`, {
119
122
  method: 'POST',
120
- headers: this.headers,
123
+ headers: await this.buildHeaders(),
121
124
  body: JSON.stringify({ collection, match, data }),
122
125
  });
123
126
  const body = await res.json();
@@ -146,7 +149,7 @@ class KoolbaseDatabase {
146
149
  async deleteWhere(collection, filters) {
147
150
  const res = await fetch(`${this.config.baseUrl}/v1/sdk/db/delete-where`, {
148
151
  method: 'POST',
149
- headers: this.headers,
152
+ headers: await this.buildHeaders(),
150
153
  body: JSON.stringify({ collection, filters }),
151
154
  });
152
155
  const body = await res.json();
@@ -194,7 +197,7 @@ class KoolbaseDatabase {
194
197
  recordId,
195
198
  });
196
199
  // Try network
197
- const res = await fetch(`${this.config.baseUrl}/v1/sdk/db/records/${recordId}`, { method: 'DELETE', headers: this.headers });
200
+ const res = await fetch(`${this.config.baseUrl}/v1/sdk/db/records/${recordId}`, { method: 'DELETE', headers: await this.buildHeaders(), });
198
201
  if (!res.ok && res.status !== 204) {
199
202
  // Queued for sync — will retry when online
200
203
  }
@@ -2,7 +2,7 @@ import { KoolbaseConfig, FunctionInvokeResult, DeployOptions, DeployResult } fro
2
2
  export declare class KoolbaseFunctions {
3
3
  private config;
4
4
  private getUserAccessToken?;
5
- constructor(config: KoolbaseConfig, getUserAccessToken?: () => string | null);
5
+ constructor(config: KoolbaseConfig, getUserAccessToken?: () => Promise<string | null>);
6
6
  deploy(options: DeployOptions): Promise<DeployResult>;
7
7
  invoke(name: string, body?: Record<string, unknown>): Promise<FunctionInvokeResult>;
8
8
  }
package/dist/functions.js CHANGED
@@ -45,7 +45,7 @@ class KoolbaseFunctions {
45
45
  'Content-Type': 'application/json',
46
46
  'x-api-key': this.config.publicKey,
47
47
  };
48
- const userToken = this.getUserAccessToken?.();
48
+ const userToken = await this.getUserAccessToken?.();
49
49
  if (userToken) {
50
50
  headers['Authorization'] = `Bearer ${userToken}`;
51
51
  }
package/dist/index.js CHANGED
@@ -67,10 +67,10 @@ exports.Koolbase = {
67
67
  if (_initialized)
68
68
  return;
69
69
  _auth = new auth_1.KoolbaseAuth(config);
70
- _db = new database_1.KoolbaseDatabase(config, () => _auth?.currentUser?.id ?? null);
71
- _storage = new storage_1.KoolbaseStorage(config, () => _auth?.accessToken ?? null);
70
+ _db = new database_1.KoolbaseDatabase(config, () => _auth?.currentUser?.id ?? null, () => _auth?.validAccessToken() ?? Promise.resolve(null));
71
+ _storage = new storage_1.KoolbaseStorage(config, () => _auth?.validAccessToken() ?? Promise.resolve(null));
72
72
  _realtime = new realtime_1.KoolbaseRealtime(config);
73
- _functions = new functions_1.KoolbaseFunctions(config, () => _auth?.accessToken ?? null);
73
+ _functions = new functions_1.KoolbaseFunctions(config, () => _auth?.validAccessToken() ?? Promise.resolve(null));
74
74
  _flags = new flags_1.KoolbaseFlags(config, 'rn-device');
75
75
  _codePush = new code_push_1.KoolbaseCodePush(config, config.codePushChannel ?? 'stable');
76
76
  // Initialize code push — loads cached bundle then checks in background
package/dist/storage.d.ts CHANGED
@@ -2,8 +2,8 @@ import { KoolbaseConfig, UploadOptions } from './types';
2
2
  export declare class KoolbaseStorage {
3
3
  private config;
4
4
  private getToken;
5
- constructor(config: KoolbaseConfig, getToken: () => string | null);
6
- private get headers();
5
+ constructor(config: KoolbaseConfig, getToken: () => Promise<string | null>);
6
+ private buildHeaders;
7
7
  upload(options: UploadOptions): Promise<{
8
8
  url: string;
9
9
  }>;
package/dist/storage.js CHANGED
@@ -6,8 +6,8 @@ class KoolbaseStorage {
6
6
  this.config = config;
7
7
  this.getToken = getToken;
8
8
  }
9
- get headers() {
10
- const token = this.getToken();
9
+ async buildHeaders() {
10
+ const token = await this.getToken();
11
11
  return {
12
12
  'x-api-key': this.config.publicKey,
13
13
  ...(token ? { Authorization: `Bearer ${token}` } : {}),
@@ -17,7 +17,7 @@ class KoolbaseStorage {
17
17
  // Get presigned upload URL
18
18
  const res = await fetch(`${this.config.baseUrl}/v1/sdk/storage/${options.bucket}/upload`, {
19
19
  method: 'POST',
20
- headers: { ...this.headers, 'Content-Type': 'application/json' },
20
+ headers: { ...(await this.buildHeaders()), 'Content-Type': 'application/json' },
21
21
  body: JSON.stringify({
22
22
  path: options.path,
23
23
  content_type: options.file.type,
@@ -39,7 +39,7 @@ class KoolbaseStorage {
39
39
  return { url: public_url };
40
40
  }
41
41
  async getDownloadUrl(bucket, path) {
42
- const res = await fetch(`${this.config.baseUrl}/v1/sdk/storage/${bucket}/download?path=${encodeURIComponent(path)}`, { headers: this.headers });
42
+ const res = await fetch(`${this.config.baseUrl}/v1/sdk/storage/${bucket}/download?path=${encodeURIComponent(path)}`, { headers: await this.buildHeaders() });
43
43
  if (!res.ok) {
44
44
  const data = await res.json();
45
45
  throw new Error(data.error ?? 'Failed to get download URL');
@@ -50,7 +50,7 @@ class KoolbaseStorage {
50
50
  async delete(bucket, path) {
51
51
  const res = await fetch(`${this.config.baseUrl}/v1/sdk/storage/${bucket}/delete`, {
52
52
  method: 'DELETE',
53
- headers: { ...this.headers, 'Content-Type': 'application/json' },
53
+ headers: { ...(await this.buildHeaders()), 'Content-Type': 'application/json' },
54
54
  body: JSON.stringify({ path }),
55
55
  });
56
56
  if (!res.ok && res.status !== 204) {
@@ -3,10 +3,11 @@ type SyncCallback = () => void;
3
3
  export declare class SyncEngine {
4
4
  private config;
5
5
  private getUserId;
6
+ private getToken;
6
7
  private onSyncComplete?;
7
8
  private unsubscribe?;
8
9
  private isSyncing;
9
- constructor(config: KoolbaseConfig, getUserId: () => string | null, onSyncComplete?: SyncCallback);
10
+ constructor(config: KoolbaseConfig, getUserId: () => string | null, getToken: () => Promise<string | null>, onSyncComplete?: SyncCallback);
10
11
  start(): void;
11
12
  stop(): void;
12
13
  flush(): Promise<void>;
@@ -7,10 +7,11 @@ exports.SyncEngine = void 0;
7
7
  const netinfo_1 = __importDefault(require("@react-native-community/netinfo"));
8
8
  const cache_store_1 = require("./cache-store");
9
9
  class SyncEngine {
10
- constructor(config, getUserId, onSyncComplete) {
10
+ constructor(config, getUserId, getToken, onSyncComplete) {
11
11
  this.isSyncing = false;
12
12
  this.config = config;
13
13
  this.getUserId = getUserId;
14
+ this.getToken = getToken;
14
15
  this.onSyncComplete = onSyncComplete;
15
16
  }
16
17
  start() {
@@ -50,9 +51,11 @@ class SyncEngine {
50
51
  }
51
52
  }
52
53
  async executeWrite(write) {
54
+ const token = await this.getToken();
53
55
  const headers = {
54
56
  'Content-Type': 'application/json',
55
57
  'x-api-key': this.config.publicKey,
58
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
56
59
  };
57
60
  if (write.type === 'insert') {
58
61
  const res = await fetch(`${this.config.baseUrl}/v1/sdk/db/insert`, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techfinityedge/koolbase-react-native",
3
- "version": "2.4.0",
3
+ "version": "3.0.0",
4
4
  "description": "React Native SDK for Koolbase \u2014 auth, database, storage, realtime, feature flags, and functions in one package.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",