@codixus/client 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +161 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -2
- package/dist/index.d.ts +40 -2
- package/dist/index.js +161 -37
- package/dist/index.js.map +1 -1
- package/dist/push-expo/index.cjs +123 -0
- package/dist/push-expo/index.cjs.map +1 -0
- package/dist/push-expo/index.d.cts +8 -0
- package/dist/push-expo/index.d.ts +8 -0
- package/dist/push-expo/index.js +88 -0
- package/dist/push-expo/index.js.map +1 -0
- package/dist/react/index.d.cts +3 -2
- package/dist/react/index.d.ts +3 -2
- package/dist/types-maS8y9s9.d.cts +14 -0
- package/dist/types-maS8y9s9.d.ts +14 -0
- package/package.json +15 -4
package/dist/index.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// src/auth/auth-manager.ts
|
|
2
2
|
var AuthManager = class {
|
|
3
|
-
constructor(storage, storageKey) {
|
|
3
|
+
constructor(storage, storageKey, options) {
|
|
4
4
|
this.storage = storage;
|
|
5
5
|
this.storageKey = storageKey;
|
|
6
|
+
this.deviceIdProvider = options?.deviceIdProvider ?? null;
|
|
7
|
+
this.autoSignInConfig = options?.autoSignIn ?? null;
|
|
6
8
|
}
|
|
9
|
+
storage;
|
|
7
10
|
accessToken = null;
|
|
8
11
|
refreshTokenValue = null;
|
|
9
12
|
user = null;
|
|
@@ -12,45 +15,72 @@ var AuthManager = class {
|
|
|
12
15
|
storageKey;
|
|
13
16
|
api;
|
|
14
17
|
deviceId = null;
|
|
18
|
+
deviceIdProvider;
|
|
19
|
+
autoSignInConfig;
|
|
20
|
+
initPromise = null;
|
|
21
|
+
signInPromise = null;
|
|
15
22
|
/** @internal */
|
|
16
23
|
_setApi(api) {
|
|
17
24
|
this.api = api;
|
|
18
25
|
}
|
|
19
26
|
async init() {
|
|
20
|
-
if (
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
27
|
+
if (this.initPromise) return this.initPromise;
|
|
28
|
+
this.initPromise = this._init().catch((err) => {
|
|
29
|
+
this.initPromise = null;
|
|
30
|
+
throw err;
|
|
31
|
+
});
|
|
32
|
+
return this.initPromise;
|
|
33
|
+
}
|
|
34
|
+
async _init() {
|
|
35
|
+
if (this.storage) {
|
|
36
|
+
try {
|
|
37
|
+
const storedRefresh = await this.storage.getItem(
|
|
38
|
+
`${this.storageKey}_refresh_token`
|
|
39
|
+
);
|
|
40
|
+
const storedUser = await this.storage.getItem(
|
|
41
|
+
`${this.storageKey}_user`
|
|
42
|
+
);
|
|
43
|
+
const storedDeviceId = await this.storage.getItem(
|
|
44
|
+
`${this.storageKey}_device_id`
|
|
45
|
+
);
|
|
46
|
+
if (storedRefresh) {
|
|
47
|
+
this.refreshTokenValue = storedRefresh;
|
|
48
|
+
}
|
|
49
|
+
if (storedUser) {
|
|
50
|
+
try {
|
|
51
|
+
this.user = JSON.parse(storedUser);
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
41
54
|
}
|
|
55
|
+
if (storedDeviceId) {
|
|
56
|
+
this.deviceId = storedDeviceId;
|
|
57
|
+
}
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.warn("[CodixusClient] Failed to restore auth state from storage:", error);
|
|
42
60
|
}
|
|
43
|
-
|
|
44
|
-
|
|
61
|
+
}
|
|
62
|
+
if (this.autoSignInConfig?.enabled && !this.refreshTokenValue) {
|
|
63
|
+
try {
|
|
64
|
+
const deviceInfo = await this.autoSignInConfig.getDeviceInfo();
|
|
65
|
+
const metadata = this.autoSignInConfig.getMetadata ? await this.autoSignInConfig.getMetadata() : void 0;
|
|
66
|
+
await this.signIn({ deviceInfo, metadata });
|
|
67
|
+
} catch (error) {
|
|
68
|
+
this.autoSignInConfig.onError?.(error);
|
|
45
69
|
}
|
|
46
|
-
} catch (error) {
|
|
47
|
-
console.warn("[CodixusClient] Failed to restore auth state from storage:", error);
|
|
48
70
|
}
|
|
49
71
|
this._isLoading = false;
|
|
50
72
|
this.notify();
|
|
51
73
|
}
|
|
52
74
|
async signIn(params) {
|
|
53
|
-
|
|
75
|
+
if (this.signInPromise) return this.signInPromise;
|
|
76
|
+
this.signInPromise = this._signIn(params).finally(() => {
|
|
77
|
+
this.signInPromise = null;
|
|
78
|
+
});
|
|
79
|
+
return this.signInPromise;
|
|
80
|
+
}
|
|
81
|
+
async _signIn(params) {
|
|
82
|
+
const providerId = this.deviceIdProvider ? await this.deviceIdProvider.getDeviceId() : null;
|
|
83
|
+
const deviceId = params.deviceId ?? this.deviceId ?? providerId ?? this.generateDeviceId();
|
|
54
84
|
const response = await this.api.post("/auth/token", {
|
|
55
85
|
deviceId,
|
|
56
86
|
deviceInfo: params.deviceInfo,
|
|
@@ -62,15 +92,19 @@ var AuthManager = class {
|
|
|
62
92
|
this.user = data.user;
|
|
63
93
|
this.deviceId = deviceId;
|
|
64
94
|
if (this.storage) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
95
|
+
try {
|
|
96
|
+
await this.storage.setItem(
|
|
97
|
+
`${this.storageKey}_refresh_token`,
|
|
98
|
+
data.refreshToken
|
|
99
|
+
);
|
|
100
|
+
await this.storage.setItem(
|
|
101
|
+
`${this.storageKey}_user`,
|
|
102
|
+
JSON.stringify(data.user)
|
|
103
|
+
);
|
|
104
|
+
await this.storage.setItem(`${this.storageKey}_device_id`, deviceId);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
console.warn("[CodixusClient] Failed to persist auth state:", error);
|
|
107
|
+
}
|
|
74
108
|
}
|
|
75
109
|
this.notify();
|
|
76
110
|
return { user: data.user, isNewUser: data.isNewUser };
|
|
@@ -119,6 +153,8 @@ var AuthManager = class {
|
|
|
119
153
|
this.accessToken = null;
|
|
120
154
|
this.refreshTokenValue = null;
|
|
121
155
|
this.user = null;
|
|
156
|
+
this.initPromise = null;
|
|
157
|
+
this.signInPromise = null;
|
|
122
158
|
if (this.storage) {
|
|
123
159
|
await this.storage.removeItem(`${this.storageKey}_refresh_token`);
|
|
124
160
|
await this.storage.removeItem(`${this.storageKey}_user`);
|
|
@@ -233,6 +269,7 @@ var ApiClient = class {
|
|
|
233
269
|
}
|
|
234
270
|
);
|
|
235
271
|
}
|
|
272
|
+
authManager;
|
|
236
273
|
instance;
|
|
237
274
|
refreshPromise = null;
|
|
238
275
|
appSecret;
|
|
@@ -259,6 +296,8 @@ var Collection = class {
|
|
|
259
296
|
this.api = api;
|
|
260
297
|
this.basePath = basePath;
|
|
261
298
|
}
|
|
299
|
+
api;
|
|
300
|
+
basePath;
|
|
262
301
|
async find(filter, options) {
|
|
263
302
|
const params = new URLSearchParams();
|
|
264
303
|
if (filter && Object.keys(filter).length > 0) {
|
|
@@ -323,6 +362,84 @@ var Collection = class {
|
|
|
323
362
|
}
|
|
324
363
|
};
|
|
325
364
|
|
|
365
|
+
// src/push/push-manager.ts
|
|
366
|
+
function extractDeliveryId(payload) {
|
|
367
|
+
if (typeof payload.deliveryId === "string" && payload.deliveryId) {
|
|
368
|
+
return payload.deliveryId;
|
|
369
|
+
}
|
|
370
|
+
const data = payload.data;
|
|
371
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
372
|
+
const nested = data.deliveryId;
|
|
373
|
+
if (typeof nested === "string" && nested) {
|
|
374
|
+
return nested;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return void 0;
|
|
378
|
+
}
|
|
379
|
+
var PushManager = class {
|
|
380
|
+
constructor(adapter, api, auth) {
|
|
381
|
+
this.adapter = adapter;
|
|
382
|
+
this.api = api;
|
|
383
|
+
this.auth = auth;
|
|
384
|
+
}
|
|
385
|
+
adapter;
|
|
386
|
+
api;
|
|
387
|
+
auth;
|
|
388
|
+
async register() {
|
|
389
|
+
const authToken = await this.auth.getToken();
|
|
390
|
+
if (!authToken) {
|
|
391
|
+
throw new Error("Not authenticated");
|
|
392
|
+
}
|
|
393
|
+
const adapterToken = await this.adapter.getToken();
|
|
394
|
+
if (!adapterToken) {
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
const body = {
|
|
398
|
+
token: adapterToken.token,
|
|
399
|
+
provider: adapterToken.provider,
|
|
400
|
+
platform: adapterToken.platform
|
|
401
|
+
};
|
|
402
|
+
try {
|
|
403
|
+
body.permissionStatus = await this.adapter.getPermissionStatus();
|
|
404
|
+
} catch {
|
|
405
|
+
}
|
|
406
|
+
await this.api.post("/push/register", body);
|
|
407
|
+
}
|
|
408
|
+
async unregister() {
|
|
409
|
+
const authToken = await this.auth.getToken();
|
|
410
|
+
if (!authToken) {
|
|
411
|
+
throw new Error("Not authenticated");
|
|
412
|
+
}
|
|
413
|
+
await this.api.post("/push/unregister", {});
|
|
414
|
+
}
|
|
415
|
+
async requestPermission() {
|
|
416
|
+
return this.adapter.requestPermission();
|
|
417
|
+
}
|
|
418
|
+
async getPermissionStatus() {
|
|
419
|
+
return this.adapter.getPermissionStatus();
|
|
420
|
+
}
|
|
421
|
+
addNotificationOpenedListener(handler) {
|
|
422
|
+
return this.adapter.addNotificationOpenedListener((payload) => {
|
|
423
|
+
handler(payload);
|
|
424
|
+
const deliveryId = extractDeliveryId(payload);
|
|
425
|
+
if (deliveryId) {
|
|
426
|
+
void this.reportOpen(deliveryId);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
addNotificationReceivedListener(handler) {
|
|
431
|
+
return this.adapter.addNotificationReceivedListener(handler);
|
|
432
|
+
}
|
|
433
|
+
async reportOpen(deliveryId) {
|
|
434
|
+
try {
|
|
435
|
+
const authToken = await this.auth.getToken();
|
|
436
|
+
if (!authToken) return;
|
|
437
|
+
await this.api.post("/push/open", { deliveryId });
|
|
438
|
+
} catch {
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
|
|
326
443
|
// src/index.ts
|
|
327
444
|
import {
|
|
328
445
|
CodixusError,
|
|
@@ -331,12 +448,19 @@ import {
|
|
|
331
448
|
var CodixusClient = class {
|
|
332
449
|
auth;
|
|
333
450
|
api;
|
|
451
|
+
push;
|
|
334
452
|
constructor(config) {
|
|
335
453
|
const storageKey = config.storageKey ?? "codixus";
|
|
336
454
|
const storage = config.storage ?? null;
|
|
337
|
-
this.auth = new AuthManager(storage, storageKey
|
|
455
|
+
this.auth = new AuthManager(storage, storageKey, {
|
|
456
|
+
deviceIdProvider: config.deviceIdProvider ?? null,
|
|
457
|
+
autoSignIn: config.autoSignIn ?? null
|
|
458
|
+
});
|
|
338
459
|
this.api = new ApiClient(config.apiUrl, this.auth, config.appSecret);
|
|
339
460
|
this.auth._setApi(this.api);
|
|
461
|
+
if (config.push) {
|
|
462
|
+
this.push = new PushManager(config.push, this.api, this.auth);
|
|
463
|
+
}
|
|
340
464
|
}
|
|
341
465
|
/**
|
|
342
466
|
* Create a typed collection accessor.
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth/auth-manager.ts","../src/api/api-client.ts","../src/db/collection.ts","../src/index.ts"],"sourcesContent":["import type {\n AuthTokenResponse,\n DeviceInfo,\n DeviceMetadata,\n} from \"@codixus/shared\";\nimport type { ApiClient } from \"../api/api-client.js\";\n\nexport interface StorageAdapter {\n getItem(key: string): Promise<string | null> | string | null;\n setItem(key: string, value: string): Promise<void> | void;\n removeItem(key: string): Promise<void> | void;\n}\n\nexport interface SignInParams {\n deviceId?: string;\n deviceInfo: DeviceInfo;\n metadata?: DeviceMetadata;\n}\n\nexport interface AuthState {\n isAuthenticated: boolean;\n isLoading: boolean;\n user: Record<string, unknown> | null;\n}\n\ntype AuthStateListener = (state: AuthState) => void;\n\nexport class AuthManager {\n private accessToken: string | null = null;\n private refreshTokenValue: string | null = null;\n private user: Record<string, unknown> | null = null;\n private listeners: Set<AuthStateListener> = new Set();\n private _isLoading = true;\n private storageKey: string;\n private api!: ApiClient;\n private deviceId: string | null = null;\n\n constructor(\n private storage: StorageAdapter | null,\n storageKey: string,\n ) {\n this.storageKey = storageKey;\n }\n\n /** @internal */\n _setApi(api: ApiClient): void {\n this.api = api;\n }\n\n async init(): Promise<void> {\n if (!this.storage) {\n this._isLoading = false;\n return;\n }\n\n try {\n const storedRefresh = await this.storage.getItem(\n `${this.storageKey}_refresh_token`,\n );\n const storedUser = await this.storage.getItem(\n `${this.storageKey}_user`,\n );\n const storedDeviceId = await this.storage.getItem(\n `${this.storageKey}_device_id`,\n );\n\n if (storedRefresh) {\n this.refreshTokenValue = storedRefresh;\n }\n if (storedUser) {\n try {\n this.user = JSON.parse(storedUser);\n } catch {\n // Corrupted user data in storage, ignore\n }\n }\n if (storedDeviceId) {\n this.deviceId = storedDeviceId;\n }\n } catch (error) {\n console.warn(\"[CodixusClient] Failed to restore auth state from storage:\", error);\n }\n\n this._isLoading = false;\n this.notify();\n }\n\n async signIn(\n params: SignInParams,\n ): Promise<{ user: Record<string, unknown>; isNewUser: boolean }> {\n const deviceId = params.deviceId ?? this.deviceId ?? this.generateDeviceId();\n\n const response = await this.api.post<AuthTokenResponse>(\"/auth/token\", {\n deviceId,\n deviceInfo: params.deviceInfo,\n metadata: params.metadata,\n });\n\n const data = response.data;\n this.accessToken = data.accessToken;\n this.refreshTokenValue = data.refreshToken;\n this.user = data.user;\n this.deviceId = deviceId;\n\n // Persist\n if (this.storage) {\n await this.storage.setItem(\n `${this.storageKey}_refresh_token`,\n data.refreshToken,\n );\n await this.storage.setItem(\n `${this.storageKey}_user`,\n JSON.stringify(data.user),\n );\n await this.storage.setItem(`${this.storageKey}_device_id`, deviceId);\n }\n\n this.notify();\n return { user: data.user, isNewUser: data.isNewUser };\n }\n\n async getToken(): Promise<string | null> {\n if (this.accessToken) return this.accessToken;\n\n // Try refresh\n if (this.refreshTokenValue) {\n try {\n await this.forceRefresh();\n return this.accessToken;\n } catch {\n return null;\n }\n }\n\n return null;\n }\n\n async forceRefresh(): Promise<string | null> {\n if (!this.refreshTokenValue) return null;\n\n try {\n const response = await this.api.post<{\n success: boolean;\n accessToken: string;\n refreshToken: string;\n }>(\"/auth/refresh\", {\n refreshToken: this.refreshTokenValue,\n });\n\n this.accessToken = response.data.accessToken;\n this.refreshTokenValue = response.data.refreshToken;\n\n if (this.storage) {\n await this.storage.setItem(\n `${this.storageKey}_refresh_token`,\n response.data.refreshToken,\n );\n }\n\n return this.accessToken;\n } catch {\n // Refresh failed, clear auth state\n await this.signOut();\n return null;\n }\n }\n\n async signOut(): Promise<void> {\n // Notify server\n if (this.refreshTokenValue) {\n try {\n await this.api.post(\"/auth/logout\", {\n refreshToken: this.refreshTokenValue,\n });\n } catch {}\n }\n\n this.accessToken = null;\n this.refreshTokenValue = null;\n this.user = null;\n\n if (this.storage) {\n await this.storage.removeItem(`${this.storageKey}_refresh_token`);\n await this.storage.removeItem(`${this.storageKey}_user`);\n await this.storage.removeItem(`${this.storageKey}_device_id`);\n }\n\n this.notify();\n }\n\n getState(): AuthState {\n return {\n isAuthenticated: this.accessToken !== null || this.refreshTokenValue !== null,\n isLoading: this._isLoading,\n user: this.user,\n };\n }\n\n getDeviceId(): string | null {\n return this.deviceId;\n }\n\n onAuthStateChange(listener: AuthStateListener): () => void {\n this.listeners.add(listener);\n // Call immediately with current state\n listener(this.getState());\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /** @internal - used by API interceptor */\n _getAccessToken(): string | null {\n return this.accessToken;\n }\n\n /** @internal - called by API interceptor after refresh */\n _setAccessToken(token: string): void {\n this.accessToken = token;\n }\n\n private notify(): void {\n const state = this.getState();\n for (const listener of this.listeners) {\n listener(state);\n }\n }\n\n private generateDeviceId(): string {\n const bytes = new Uint8Array(16);\n if (typeof globalThis.crypto?.getRandomValues === \"function\") {\n globalThis.crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < 16; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n return \"dev-\" + Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n }\n}\n","import axios, {\n type AxiosInstance,\n type AxiosRequestConfig,\n type AxiosResponse,\n} from \"axios\";\nimport type { AuthManager } from \"../auth/auth-manager.js\";\n\n// Crypto functions — injected from outside to avoid platform-specific imports\nexport interface CryptoProvider {\n sha256(data: string): Promise<string>;\n hmacSha256(secret: string, data: string): Promise<string>;\n randomUUID(): string;\n}\n\n// Default: no-op (signing disabled if no crypto provider)\nlet _crypto: CryptoProvider | null = null;\n\nexport function setCryptoProvider(provider: CryptoProvider): void {\n _crypto = provider;\n}\n\nfunction generateNonce(): string {\n if (_crypto) return _crypto.randomUUID();\n if (typeof globalThis.crypto?.randomUUID === \"function\") {\n return globalThis.crypto.randomUUID();\n }\n const bytes = new Uint8Array(16);\n if (typeof globalThis.crypto?.getRandomValues === \"function\") {\n globalThis.crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < 16; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n return Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport class ApiClient {\n readonly instance: AxiosInstance;\n private refreshPromise: Promise<string | null> | null = null;\n private appSecret: string | undefined;\n\n constructor(\n baseURL: string,\n private authManager: AuthManager,\n appSecret?: string,\n ) {\n this.appSecret = appSecret;\n\n this.instance = axios.create({\n baseURL,\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n // Request interceptor: add Bearer token + signing\n this.instance.interceptors.request.use(async (config) => {\n // Skip auth for auth endpoints\n if (!config.url?.includes(\"/auth/\")) {\n const token = this.authManager._getAccessToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n }\n\n // Request signing (only if crypto provider is set)\n if (this.appSecret && _crypto) {\n const timestamp = Date.now().toString();\n const nonce = _crypto.randomUUID();\n const body =\n config.data && typeof config.data === \"object\"\n ? JSON.stringify(config.data)\n : (config.data ?? \"\");\n const bodyHash = body ? await _crypto.sha256(body) : \"\";\n const method = (config.method ?? \"GET\").toUpperCase();\n const url = config.url ?? \"/\";\n const payload = [method, url, timestamp, nonce, bodyHash].join(\"\\n\");\n const signature = await _crypto.hmacSha256(this.appSecret, payload);\n\n config.headers[\"X-Codixus-Timestamp\"] = timestamp;\n config.headers[\"X-Codixus-Nonce\"] = nonce;\n config.headers[\"X-Codixus-Signature\"] = signature;\n }\n\n return config;\n });\n\n // Response interceptor: handle 401 with token refresh\n this.instance.interceptors.response.use(\n (response) => response,\n async (error) => {\n if (error.response?.status === 401) {\n const originalRequest = error.config;\n if (originalRequest && !originalRequest._retry) {\n originalRequest._retry = true;\n\n try {\n if (!this.refreshPromise) {\n this.refreshPromise = this.authManager\n .forceRefresh()\n .finally(() => {\n this.refreshPromise = null;\n });\n }\n\n const newToken = await this.refreshPromise;\n if (newToken) {\n originalRequest.headers.Authorization = `Bearer ${newToken}`;\n return this.instance(originalRequest);\n }\n } catch (refreshError) {\n console.warn(\"[CodixusClient] Token refresh failed:\", refreshError);\n }\n }\n }\n return Promise.reject(error);\n },\n );\n }\n\n async get<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.instance.get<T>(url, config);\n }\n\n async post<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.instance.post<T>(url, data, config);\n }\n\n async patch<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.instance.patch<T>(url, data, config);\n }\n\n async delete<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.instance.delete<T>(url, config);\n }\n\n async put<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.instance.put<T>(url, data, config);\n }\n}\n","import type { ApiClient } from \"../api/api-client.js\";\n\nexport interface FindOptions {\n sort?: Record<string, 1 | -1>;\n limit?: number;\n skip?: number;\n cursor?: string | number;\n}\n\nexport class Collection<T = Record<string, unknown>> {\n constructor(\n private api: ApiClient,\n private basePath: string,\n ) {}\n\n async find(\n filter?: Record<string, unknown>,\n options?: FindOptions,\n ): Promise<T[]> {\n const params = new URLSearchParams();\n if (filter && Object.keys(filter).length > 0) {\n params.set(\"filter\", JSON.stringify(filter));\n }\n if (options?.sort) params.set(\"sort\", JSON.stringify(options.sort));\n if (options?.limit) params.set(\"limit\", String(options.limit));\n if (options?.skip) params.set(\"skip\", String(options.skip));\n if (options?.cursor) params.set(\"cursor\", String(options.cursor));\n\n const qs = params.toString();\n const url = qs ? `${this.basePath}?${qs}` : this.basePath;\n const { data } = await this.api.get<{ success: boolean; data: T[]; nextCursor?: string | null }>(url);\n return data.data;\n }\n\n async findWithCursor(\n filter?: Record<string, unknown>,\n options?: FindOptions,\n ): Promise<{ data: T[]; nextCursor: string | number | null }> {\n const params = new URLSearchParams();\n if (filter && Object.keys(filter).length > 0) {\n params.set(\"filter\", JSON.stringify(filter));\n }\n if (options?.sort) params.set(\"sort\", JSON.stringify(options.sort));\n if (options?.limit) params.set(\"limit\", String(options.limit));\n if (options?.cursor) params.set(\"cursor\", String(options.cursor));\n\n const qs = params.toString();\n const url = qs ? `${this.basePath}?${qs}` : this.basePath;\n const { data } = await this.api.get<{ success: boolean; data: T[]; nextCursor: string | number | null }>(url);\n return { data: data.data, nextCursor: data.nextCursor };\n }\n\n async findById(id: string): Promise<T | null> {\n try {\n const { data } = await this.api.get<{ success: boolean; data: T }>(\n `${this.basePath}/${id}`,\n );\n return data.data;\n } catch (error: any) {\n if (error.response?.status === 404) return null;\n throw error;\n }\n }\n\n async create(doc: Partial<T> & Record<string, unknown>): Promise<T> {\n const { data } = await this.api.post<{ success: boolean; data: T }>(\n this.basePath,\n doc,\n );\n return data.data;\n }\n\n async updateById(\n id: string,\n update: Record<string, unknown>,\n ): Promise<T> {\n const { data } = await this.api.patch<{ success: boolean; data: T }>(\n `${this.basePath}/${id}`,\n { update },\n );\n return data.data;\n }\n\n async deleteById(id: string): Promise<void> {\n await this.api.delete(`${this.basePath}/${id}`);\n }\n\n async count(filter?: Record<string, unknown>): Promise<number> {\n const { data } = await this.api.post<{ success: boolean; count: number }>(\n `${this.basePath}/count`,\n { filter: filter ?? {} },\n );\n return data.count;\n }\n}\n","import {\n AuthManager,\n type StorageAdapter,\n type SignInParams,\n type AuthState,\n} from \"./auth/auth-manager.js\";\nimport { ApiClient } from \"./api/api-client.js\";\nimport { Collection, type FindOptions } from \"./db/collection.js\";\n\nexport interface CodixusClientConfig {\n apiUrl: string;\n storageKey?: string;\n storage?: StorageAdapter | null;\n appSecret?: string;\n}\n\nexport class CodixusClient {\n readonly auth: AuthManager;\n readonly api: ApiClient;\n\n constructor(config: CodixusClientConfig) {\n const storageKey = config.storageKey ?? \"codixus\";\n const storage = config.storage ?? null;\n\n this.auth = new AuthManager(storage, storageKey);\n this.api = new ApiClient(config.apiUrl, this.auth, config.appSecret);\n this.auth._setApi(this.api);\n }\n\n /**\n * Create a typed collection accessor.\n * Maps to auto REST routes on server: codixus.rest(Model)\n *\n * @example\n * interface Product { _id: string; name: string; price: number; }\n * const products = codixus.collection<Product>(\"products\");\n * const all = await products.find(); // Product[]\n * const one = await products.findById(\"abc\"); // Product | null\n */\n collection<T>(name: string): Collection<T> {\n return new Collection<T>(this.api, `/api/${name}`);\n }\n\n async init(): Promise<void> {\n await this.auth.init();\n }\n}\n\nexport {\n type StorageAdapter,\n type SignInParams,\n type AuthState,\n} from \"./auth/auth-manager.js\";\nexport { ApiClient, setCryptoProvider, type CryptoProvider } from \"./api/api-client.js\";\nexport { Collection, type FindOptions } from \"./db/collection.js\";\n\n// Re-export shared types\nexport {\n type AuthUser,\n type TokenPair,\n type DeviceInfo,\n type DeviceMetadata,\n type AuthTokenRequest,\n type AuthTokenResponse,\n type ApiResponse,\n CodixusError,\n ErrorCodes,\n} from \"@codixus/shared\";\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/auth/auth-manager.ts","../src/api/api-client.ts","../src/db/collection.ts","../src/push/push-manager.ts","../src/index.ts"],"sourcesContent":["import type {\n AuthTokenResponse,\n DeviceInfo,\n DeviceMetadata,\n} from \"@codixus/shared\";\nimport type { ApiClient } from \"../api/api-client.js\";\n\nexport interface StorageAdapter {\n getItem(key: string): Promise<string | null> | string | null;\n setItem(key: string, value: string): Promise<void> | void;\n removeItem(key: string): Promise<void> | void;\n}\n\n// Host-injected source for a stable, OS-level device identifier (IDFV on\n// iOS, ANDROID_ID on Android, etc.). The SDK calls this when it needs to\n// obtain a deviceId and has nothing in storage. Returning null lets the\n// SDK fall back to a generated UUID. Keeping this an interface (instead\n// of importing expo-application) keeps the SDK platform-agnostic.\nexport interface DeviceIdProvider {\n getDeviceId(): Promise<string | null> | string | null;\n}\n\n// Optional auto signIn driven by the SDK on init(). When provided, after\n// init() restores from storage and the user is still unauthenticated, the\n// SDK calls signIn with the host-supplied device info/metadata. This\n// removes the need for every host app to wire its own boot signIn.\nexport interface AutoSignInConfig {\n enabled: boolean;\n getDeviceInfo(): DeviceInfo | Promise<DeviceInfo>;\n getMetadata?(): DeviceMetadata | Promise<DeviceMetadata>;\n onError?(error: unknown): void;\n}\n\nexport interface SignInParams {\n deviceId?: string;\n deviceInfo: DeviceInfo;\n metadata?: DeviceMetadata;\n}\n\nexport interface AuthState {\n isAuthenticated: boolean;\n isLoading: boolean;\n user: Record<string, unknown> | null;\n}\n\ntype AuthStateListener = (state: AuthState) => void;\n\nexport class AuthManager {\n private accessToken: string | null = null;\n private refreshTokenValue: string | null = null;\n private user: Record<string, unknown> | null = null;\n private listeners: Set<AuthStateListener> = new Set();\n private _isLoading = true;\n private storageKey: string;\n private api!: ApiClient;\n private deviceId: string | null = null;\n private deviceIdProvider: DeviceIdProvider | null;\n private autoSignInConfig: AutoSignInConfig | null;\n private initPromise: Promise<void> | null = null;\n private signInPromise: Promise<{ user: Record<string, unknown>; isNewUser: boolean }> | null = null;\n\n constructor(\n private storage: StorageAdapter | null,\n storageKey: string,\n options?: {\n deviceIdProvider?: DeviceIdProvider | null;\n autoSignIn?: AutoSignInConfig | null;\n },\n ) {\n this.storageKey = storageKey;\n this.deviceIdProvider = options?.deviceIdProvider ?? null;\n this.autoSignInConfig = options?.autoSignIn ?? null;\n }\n\n /** @internal */\n _setApi(api: ApiClient): void {\n this.api = api;\n }\n\n async init(): Promise<void> {\n // Idempotent: concurrent or repeat callers (e.g. host module-load\n // init plus the React provider's useEffect init) share a single run\n // so autoSignIn does not fire twice and race against itself on the\n // backend. On rejection we clear the cached promise so a retry can\n // run — caching a rejected promise would brick init() for the rest\n // of the app lifetime.\n if (this.initPromise) return this.initPromise;\n this.initPromise = this._init().catch((err) => {\n this.initPromise = null;\n throw err;\n });\n return this.initPromise;\n }\n\n private async _init(): Promise<void> {\n if (this.storage) {\n try {\n const storedRefresh = await this.storage.getItem(\n `${this.storageKey}_refresh_token`,\n );\n const storedUser = await this.storage.getItem(\n `${this.storageKey}_user`,\n );\n const storedDeviceId = await this.storage.getItem(\n `${this.storageKey}_device_id`,\n );\n\n if (storedRefresh) {\n this.refreshTokenValue = storedRefresh;\n }\n if (storedUser) {\n try {\n this.user = JSON.parse(storedUser);\n } catch {\n // Corrupted user data in storage, ignore\n }\n }\n if (storedDeviceId) {\n this.deviceId = storedDeviceId;\n }\n } catch (error) {\n console.warn(\"[CodixusClient] Failed to restore auth state from storage:\", error);\n }\n }\n\n // Auto signIn: if the host app opted in and we have no live session yet\n // (cold start, app data cleared, fresh install), reach out to the\n // backend with the device-bound identifier so the existing user is\n // restored before any UI hits an authenticated route.\n if (\n this.autoSignInConfig?.enabled &&\n !this.refreshTokenValue\n ) {\n try {\n const deviceInfo = await this.autoSignInConfig.getDeviceInfo();\n const metadata = this.autoSignInConfig.getMetadata\n ? await this.autoSignInConfig.getMetadata()\n : undefined;\n await this.signIn({ deviceInfo, metadata });\n } catch (error) {\n this.autoSignInConfig.onError?.(error);\n }\n }\n\n this._isLoading = false;\n this.notify();\n }\n\n async signIn(\n params: SignInParams,\n ): Promise<{ user: Record<string, unknown>; isNewUser: boolean }> {\n // Coalesce concurrent signIn calls (e.g. autoSignIn racing a manual\n // signIn from a UI handler) onto a single network request.\n if (this.signInPromise) return this.signInPromise;\n this.signInPromise = this._signIn(params).finally(() => {\n this.signInPromise = null;\n });\n return this.signInPromise;\n }\n\n private async _signIn(\n params: SignInParams,\n ): Promise<{ user: Record<string, unknown>; isNewUser: boolean }> {\n const providerId = this.deviceIdProvider\n ? await this.deviceIdProvider.getDeviceId()\n : null;\n const deviceId =\n params.deviceId ??\n this.deviceId ??\n providerId ??\n this.generateDeviceId();\n\n const response = await this.api.post<AuthTokenResponse>(\"/auth/token\", {\n deviceId,\n deviceInfo: params.deviceInfo,\n metadata: params.metadata,\n });\n\n const data = response.data;\n this.accessToken = data.accessToken;\n this.refreshTokenValue = data.refreshToken;\n this.user = data.user;\n this.deviceId = deviceId;\n\n // Persist. Storage failures (full disk, locked keychain post-restore,\n // EncryptedSharedPreferences key invalidation) must not strand the\n // in-memory session — the user is signed in for this run; the next\n // cold start will simply re-trigger autoSignIn.\n if (this.storage) {\n try {\n await this.storage.setItem(\n `${this.storageKey}_refresh_token`,\n data.refreshToken,\n );\n await this.storage.setItem(\n `${this.storageKey}_user`,\n JSON.stringify(data.user),\n );\n await this.storage.setItem(`${this.storageKey}_device_id`, deviceId);\n } catch (error) {\n console.warn(\"[CodixusClient] Failed to persist auth state:\", error);\n }\n }\n\n this.notify();\n return { user: data.user, isNewUser: data.isNewUser };\n }\n\n async getToken(): Promise<string | null> {\n if (this.accessToken) return this.accessToken;\n\n // Try refresh\n if (this.refreshTokenValue) {\n try {\n await this.forceRefresh();\n return this.accessToken;\n } catch {\n return null;\n }\n }\n\n return null;\n }\n\n async forceRefresh(): Promise<string | null> {\n if (!this.refreshTokenValue) return null;\n\n try {\n const response = await this.api.post<{\n success: boolean;\n accessToken: string;\n refreshToken: string;\n }>(\"/auth/refresh\", {\n refreshToken: this.refreshTokenValue,\n });\n\n this.accessToken = response.data.accessToken;\n this.refreshTokenValue = response.data.refreshToken;\n\n if (this.storage) {\n await this.storage.setItem(\n `${this.storageKey}_refresh_token`,\n response.data.refreshToken,\n );\n }\n\n return this.accessToken;\n } catch {\n // Refresh failed, clear auth state\n await this.signOut();\n return null;\n }\n }\n\n async signOut(): Promise<void> {\n // Notify server\n if (this.refreshTokenValue) {\n try {\n await this.api.post(\"/auth/logout\", {\n refreshToken: this.refreshTokenValue,\n });\n } catch {}\n }\n\n this.accessToken = null;\n this.refreshTokenValue = null;\n this.user = null;\n // Reset guards so a fresh signIn flow (or a re-init triggered by a\n // host that wants to re-authenticate after sign-out) can run. The\n // signInPromise is also cleared by its own .finally, but a signOut\n // racing against an in-flight signIn shouldn't keep the stale guard.\n this.initPromise = null;\n this.signInPromise = null;\n\n if (this.storage) {\n await this.storage.removeItem(`${this.storageKey}_refresh_token`);\n await this.storage.removeItem(`${this.storageKey}_user`);\n await this.storage.removeItem(`${this.storageKey}_device_id`);\n }\n\n this.notify();\n }\n\n getState(): AuthState {\n return {\n isAuthenticated: this.accessToken !== null || this.refreshTokenValue !== null,\n isLoading: this._isLoading,\n user: this.user,\n };\n }\n\n getDeviceId(): string | null {\n return this.deviceId;\n }\n\n onAuthStateChange(listener: AuthStateListener): () => void {\n this.listeners.add(listener);\n // Call immediately with current state\n listener(this.getState());\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /** @internal - used by API interceptor */\n _getAccessToken(): string | null {\n return this.accessToken;\n }\n\n /** @internal - called by API interceptor after refresh */\n _setAccessToken(token: string): void {\n this.accessToken = token;\n }\n\n private notify(): void {\n const state = this.getState();\n for (const listener of this.listeners) {\n listener(state);\n }\n }\n\n private generateDeviceId(): string {\n const bytes = new Uint8Array(16);\n if (typeof globalThis.crypto?.getRandomValues === \"function\") {\n globalThis.crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < 16; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n return \"dev-\" + Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n }\n}\n","import axios, {\n type AxiosInstance,\n type AxiosRequestConfig,\n type AxiosResponse,\n} from \"axios\";\nimport type { AuthManager } from \"../auth/auth-manager.js\";\n\n// Crypto functions — injected from outside to avoid platform-specific imports\nexport interface CryptoProvider {\n sha256(data: string): Promise<string>;\n hmacSha256(secret: string, data: string): Promise<string>;\n randomUUID(): string;\n}\n\n// Default: no-op (signing disabled if no crypto provider)\nlet _crypto: CryptoProvider | null = null;\n\nexport function setCryptoProvider(provider: CryptoProvider): void {\n _crypto = provider;\n}\n\nfunction generateNonce(): string {\n if (_crypto) return _crypto.randomUUID();\n if (typeof globalThis.crypto?.randomUUID === \"function\") {\n return globalThis.crypto.randomUUID();\n }\n const bytes = new Uint8Array(16);\n if (typeof globalThis.crypto?.getRandomValues === \"function\") {\n globalThis.crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < 16; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n return Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport class ApiClient {\n readonly instance: AxiosInstance;\n private refreshPromise: Promise<string | null> | null = null;\n private appSecret: string | undefined;\n\n constructor(\n baseURL: string,\n private authManager: AuthManager,\n appSecret?: string,\n ) {\n this.appSecret = appSecret;\n\n this.instance = axios.create({\n baseURL,\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n // Request interceptor: add Bearer token + signing\n this.instance.interceptors.request.use(async (config) => {\n // Skip auth for auth endpoints\n if (!config.url?.includes(\"/auth/\")) {\n const token = this.authManager._getAccessToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n }\n\n // Request signing (only if crypto provider is set)\n if (this.appSecret && _crypto) {\n const timestamp = Date.now().toString();\n const nonce = _crypto.randomUUID();\n const body =\n config.data && typeof config.data === \"object\"\n ? JSON.stringify(config.data)\n : (config.data ?? \"\");\n const bodyHash = body ? await _crypto.sha256(body) : \"\";\n const method = (config.method ?? \"GET\").toUpperCase();\n const url = config.url ?? \"/\";\n const payload = [method, url, timestamp, nonce, bodyHash].join(\"\\n\");\n const signature = await _crypto.hmacSha256(this.appSecret, payload);\n\n config.headers[\"X-Codixus-Timestamp\"] = timestamp;\n config.headers[\"X-Codixus-Nonce\"] = nonce;\n config.headers[\"X-Codixus-Signature\"] = signature;\n }\n\n return config;\n });\n\n // Response interceptor: handle 401 with token refresh\n this.instance.interceptors.response.use(\n (response) => response,\n async (error) => {\n if (error.response?.status === 401) {\n const originalRequest = error.config;\n if (originalRequest && !originalRequest._retry) {\n originalRequest._retry = true;\n\n try {\n if (!this.refreshPromise) {\n this.refreshPromise = this.authManager\n .forceRefresh()\n .finally(() => {\n this.refreshPromise = null;\n });\n }\n\n const newToken = await this.refreshPromise;\n if (newToken) {\n originalRequest.headers.Authorization = `Bearer ${newToken}`;\n return this.instance(originalRequest);\n }\n } catch (refreshError) {\n console.warn(\"[CodixusClient] Token refresh failed:\", refreshError);\n }\n }\n }\n return Promise.reject(error);\n },\n );\n }\n\n async get<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.instance.get<T>(url, config);\n }\n\n async post<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.instance.post<T>(url, data, config);\n }\n\n async patch<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.instance.patch<T>(url, data, config);\n }\n\n async delete<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.instance.delete<T>(url, config);\n }\n\n async put<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.instance.put<T>(url, data, config);\n }\n}\n","import type { ApiClient } from \"../api/api-client.js\";\n\nexport interface FindOptions {\n sort?: Record<string, 1 | -1>;\n limit?: number;\n skip?: number;\n cursor?: string | number;\n}\n\nexport class Collection<T = Record<string, unknown>> {\n constructor(\n private api: ApiClient,\n private basePath: string,\n ) {}\n\n async find(\n filter?: Record<string, unknown>,\n options?: FindOptions,\n ): Promise<T[]> {\n const params = new URLSearchParams();\n if (filter && Object.keys(filter).length > 0) {\n params.set(\"filter\", JSON.stringify(filter));\n }\n if (options?.sort) params.set(\"sort\", JSON.stringify(options.sort));\n if (options?.limit) params.set(\"limit\", String(options.limit));\n if (options?.skip) params.set(\"skip\", String(options.skip));\n if (options?.cursor) params.set(\"cursor\", String(options.cursor));\n\n const qs = params.toString();\n const url = qs ? `${this.basePath}?${qs}` : this.basePath;\n const { data } = await this.api.get<{ success: boolean; data: T[]; nextCursor?: string | null }>(url);\n return data.data;\n }\n\n async findWithCursor(\n filter?: Record<string, unknown>,\n options?: FindOptions,\n ): Promise<{ data: T[]; nextCursor: string | number | null }> {\n const params = new URLSearchParams();\n if (filter && Object.keys(filter).length > 0) {\n params.set(\"filter\", JSON.stringify(filter));\n }\n if (options?.sort) params.set(\"sort\", JSON.stringify(options.sort));\n if (options?.limit) params.set(\"limit\", String(options.limit));\n if (options?.cursor) params.set(\"cursor\", String(options.cursor));\n\n const qs = params.toString();\n const url = qs ? `${this.basePath}?${qs}` : this.basePath;\n const { data } = await this.api.get<{ success: boolean; data: T[]; nextCursor: string | number | null }>(url);\n return { data: data.data, nextCursor: data.nextCursor };\n }\n\n async findById(id: string): Promise<T | null> {\n try {\n const { data } = await this.api.get<{ success: boolean; data: T }>(\n `${this.basePath}/${id}`,\n );\n return data.data;\n } catch (error: any) {\n if (error.response?.status === 404) return null;\n throw error;\n }\n }\n\n async create(doc: Partial<T> & Record<string, unknown>): Promise<T> {\n const { data } = await this.api.post<{ success: boolean; data: T }>(\n this.basePath,\n doc,\n );\n return data.data;\n }\n\n async updateById(\n id: string,\n update: Record<string, unknown>,\n ): Promise<T> {\n const { data } = await this.api.patch<{ success: boolean; data: T }>(\n `${this.basePath}/${id}`,\n { update },\n );\n return data.data;\n }\n\n async deleteById(id: string): Promise<void> {\n await this.api.delete(`${this.basePath}/${id}`);\n }\n\n async count(filter?: Record<string, unknown>): Promise<number> {\n const { data } = await this.api.post<{ success: boolean; count: number }>(\n `${this.basePath}/count`,\n { filter: filter ?? {} },\n );\n return data.count;\n }\n}\n","import type { ApiClient } from \"../api/api-client.js\";\nimport type { AuthManager } from \"../auth/auth-manager.js\";\nimport type { PushAdapter } from \"./types.js\";\n\nfunction extractDeliveryId(\n payload: Record<string, unknown>,\n): string | undefined {\n if (typeof payload.deliveryId === \"string\" && payload.deliveryId) {\n return payload.deliveryId;\n }\n const data = payload.data;\n if (data && typeof data === \"object\" && !Array.isArray(data)) {\n const nested = (data as Record<string, unknown>).deliveryId;\n if (typeof nested === \"string\" && nested) {\n return nested;\n }\n }\n return undefined;\n}\n\nexport class PushManager {\n constructor(\n private adapter: PushAdapter,\n private api: ApiClient,\n private auth: AuthManager,\n ) {}\n\n async register(): Promise<void> {\n const authToken = await this.auth.getToken();\n if (!authToken) {\n throw new Error(\"Not authenticated\");\n }\n\n const adapterToken = await this.adapter.getToken();\n if (!adapterToken) {\n return;\n }\n\n const body: Record<string, unknown> = {\n token: adapterToken.token,\n provider: adapterToken.provider,\n platform: adapterToken.platform,\n };\n\n try {\n body.permissionStatus = await this.adapter.getPermissionStatus();\n } catch {\n // omit permissionStatus, still POST\n }\n\n await this.api.post(\"/push/register\", body);\n }\n\n async unregister(): Promise<void> {\n const authToken = await this.auth.getToken();\n if (!authToken) {\n throw new Error(\"Not authenticated\");\n }\n\n await this.api.post(\"/push/unregister\", {});\n }\n\n async requestPermission(): Promise<boolean> {\n return this.adapter.requestPermission();\n }\n\n async getPermissionStatus(): Promise<\n \"granted\" | \"denied\" | \"undetermined\"\n > {\n return this.adapter.getPermissionStatus();\n }\n\n addNotificationOpenedListener(\n handler: (payload: Record<string, unknown>) => void,\n ): () => void {\n return this.adapter.addNotificationOpenedListener((payload) => {\n handler(payload);\n const deliveryId = extractDeliveryId(payload);\n if (deliveryId) {\n void this.reportOpen(deliveryId);\n }\n });\n }\n\n addNotificationReceivedListener(\n handler: (payload: Record<string, unknown>) => void,\n ): () => void {\n return this.adapter.addNotificationReceivedListener(handler);\n }\n\n private async reportOpen(deliveryId: string): Promise<void> {\n try {\n const authToken = await this.auth.getToken();\n if (!authToken) return;\n await this.api.post(\"/push/open\", { deliveryId });\n } catch {\n // fire-and-forget: swallow 404, 401, 5xx, network errors\n }\n }\n}\n","import {\n AuthManager,\n type StorageAdapter,\n type SignInParams,\n type AuthState,\n type DeviceIdProvider,\n type AutoSignInConfig,\n} from \"./auth/auth-manager.js\";\nimport { ApiClient } from \"./api/api-client.js\";\nimport { Collection, type FindOptions } from \"./db/collection.js\";\nimport { PushManager } from \"./push/push-manager.js\";\nimport type { PushAdapter } from \"./push/types.js\";\n\nexport interface CodixusClientConfig {\n apiUrl: string;\n storageKey?: string;\n storage?: StorageAdapter | null;\n appSecret?: string;\n deviceIdProvider?: DeviceIdProvider | null;\n autoSignIn?: AutoSignInConfig | null;\n push?: PushAdapter;\n}\n\nexport class CodixusClient {\n readonly auth: AuthManager;\n readonly api: ApiClient;\n readonly push?: PushManager;\n\n constructor(config: CodixusClientConfig) {\n const storageKey = config.storageKey ?? \"codixus\";\n const storage = config.storage ?? null;\n\n this.auth = new AuthManager(storage, storageKey, {\n deviceIdProvider: config.deviceIdProvider ?? null,\n autoSignIn: config.autoSignIn ?? null,\n });\n this.api = new ApiClient(config.apiUrl, this.auth, config.appSecret);\n this.auth._setApi(this.api);\n\n if (config.push) {\n this.push = new PushManager(config.push, this.api, this.auth);\n }\n }\n\n /**\n * Create a typed collection accessor.\n * Maps to auto REST routes on server: codixus.rest(Model)\n *\n * @example\n * interface Product { _id: string; name: string; price: number; }\n * const products = codixus.collection<Product>(\"products\");\n * const all = await products.find(); // Product[]\n * const one = await products.findById(\"abc\"); // Product | null\n */\n collection<T>(name: string): Collection<T> {\n return new Collection<T>(this.api, `/api/${name}`);\n }\n\n async init(): Promise<void> {\n await this.auth.init();\n }\n}\n\nexport {\n type StorageAdapter,\n type SignInParams,\n type AuthState,\n type DeviceIdProvider,\n type AutoSignInConfig,\n} from \"./auth/auth-manager.js\";\nexport { ApiClient, setCryptoProvider, type CryptoProvider } from \"./api/api-client.js\";\nexport { Collection, type FindOptions } from \"./db/collection.js\";\nexport { type PushAdapter, type PushAdapterToken } from \"./push/types.js\";\n\n// Re-export shared types\nexport {\n type AuthUser,\n type TokenPair,\n type DeviceInfo,\n type DeviceMetadata,\n type AuthTokenRequest,\n type AuthTokenResponse,\n type ApiResponse,\n CodixusError,\n ErrorCodes,\n} from \"@codixus/shared\";\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/push-expo/index.ts
|
|
31
|
+
var push_expo_exports = {};
|
|
32
|
+
__export(push_expo_exports, {
|
|
33
|
+
createExpoAdapter: () => createExpoAdapter
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(push_expo_exports);
|
|
36
|
+
var Notifications = __toESM(require("expo-notifications"), 1);
|
|
37
|
+
var import_react_native = require("react-native");
|
|
38
|
+
function resolvePlatform() {
|
|
39
|
+
if (import_react_native.Platform.OS === "ios" || import_react_native.Platform.OS === "android") {
|
|
40
|
+
return import_react_native.Platform.OS;
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
function flattenPayload(notification) {
|
|
45
|
+
const data = notification.request.content.data;
|
|
46
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
47
|
+
return { ...data };
|
|
48
|
+
}
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
function mapPermissionStatus(status) {
|
|
52
|
+
if (status === "granted") {
|
|
53
|
+
return "granted";
|
|
54
|
+
}
|
|
55
|
+
if (status === "denied") {
|
|
56
|
+
return "denied";
|
|
57
|
+
}
|
|
58
|
+
return "undetermined";
|
|
59
|
+
}
|
|
60
|
+
var noopUnsubscribe = () => {
|
|
61
|
+
};
|
|
62
|
+
function createNoopAdapter() {
|
|
63
|
+
return {
|
|
64
|
+
getPermissionStatus: async () => "denied",
|
|
65
|
+
requestPermission: async () => false,
|
|
66
|
+
getToken: async () => null,
|
|
67
|
+
addNotificationReceivedListener: () => noopUnsubscribe,
|
|
68
|
+
addNotificationOpenedListener: () => noopUnsubscribe
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function createExpoAdapter(opts) {
|
|
72
|
+
const platform = resolvePlatform();
|
|
73
|
+
if (!platform) {
|
|
74
|
+
return createNoopAdapter();
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
async getPermissionStatus() {
|
|
78
|
+
const { status } = await Notifications.getPermissionsAsync();
|
|
79
|
+
return mapPermissionStatus(status);
|
|
80
|
+
},
|
|
81
|
+
async requestPermission() {
|
|
82
|
+
const { status } = await Notifications.requestPermissionsAsync();
|
|
83
|
+
return status === "granted";
|
|
84
|
+
},
|
|
85
|
+
async getToken() {
|
|
86
|
+
const permission = await this.getPermissionStatus();
|
|
87
|
+
if (permission !== "granted") {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const result = await Notifications.getExpoPushTokenAsync({
|
|
92
|
+
projectId: opts.projectId
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
token: result.data,
|
|
96
|
+
provider: "expo",
|
|
97
|
+
platform
|
|
98
|
+
};
|
|
99
|
+
} catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
addNotificationReceivedListener(handler) {
|
|
104
|
+
const subscription = Notifications.addNotificationReceivedListener(
|
|
105
|
+
(notification) => {
|
|
106
|
+
handler(flattenPayload(notification));
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
return () => subscription.remove();
|
|
110
|
+
},
|
|
111
|
+
addNotificationOpenedListener(handler) {
|
|
112
|
+
const subscription = Notifications.addNotificationResponseReceivedListener((response) => {
|
|
113
|
+
handler(flattenPayload(response.notification));
|
|
114
|
+
});
|
|
115
|
+
return () => subscription.remove();
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
120
|
+
0 && (module.exports = {
|
|
121
|
+
createExpoAdapter
|
|
122
|
+
});
|
|
123
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/push-expo/index.ts"],"sourcesContent":["import * as Notifications from \"expo-notifications\";\nimport { Platform } from \"react-native\";\nimport type { PushAdapter, PushAdapterToken } from \"../push/types.js\";\n\nexport type { PushAdapter, PushAdapterToken } from \"../push/types.js\";\n\ntype PlatformOS = \"ios\" | \"android\";\n\nfunction resolvePlatform(): PlatformOS | null {\n if (Platform.OS === \"ios\" || Platform.OS === \"android\") {\n return Platform.OS;\n }\n return null;\n}\n\nfunction flattenPayload(\n notification: Notifications.Notification,\n): Record<string, unknown> {\n const data = notification.request.content.data;\n if (data && typeof data === \"object\" && !Array.isArray(data)) {\n return { ...(data as Record<string, unknown>) };\n }\n return {};\n}\n\nfunction mapPermissionStatus(\n status: string,\n): \"granted\" | \"denied\" | \"undetermined\" {\n if (status === \"granted\") {\n return \"granted\";\n }\n if (status === \"denied\") {\n return \"denied\";\n }\n return \"undetermined\";\n}\n\nconst noopUnsubscribe = (): void => {};\n\nfunction createNoopAdapter(): PushAdapter {\n return {\n getPermissionStatus: async () => \"denied\",\n requestPermission: async () => false,\n getToken: async () => null,\n addNotificationReceivedListener: () => noopUnsubscribe,\n addNotificationOpenedListener: () => noopUnsubscribe,\n };\n}\n\nexport function createExpoAdapter(opts: { projectId: string }): PushAdapter {\n const platform = resolvePlatform();\n if (!platform) {\n return createNoopAdapter();\n }\n\n return {\n async getPermissionStatus() {\n const { status } = await Notifications.getPermissionsAsync();\n return mapPermissionStatus(status);\n },\n\n async requestPermission() {\n const { status } = await Notifications.requestPermissionsAsync();\n return status === \"granted\";\n },\n\n async getToken(): Promise<PushAdapterToken | null> {\n const permission = await this.getPermissionStatus();\n if (permission !== \"granted\") {\n return null;\n }\n\n try {\n const result = await Notifications.getExpoPushTokenAsync({\n projectId: opts.projectId,\n });\n return {\n token: result.data,\n provider: \"expo\",\n platform,\n };\n } catch {\n return null;\n }\n },\n\n addNotificationReceivedListener(handler) {\n const subscription = Notifications.addNotificationReceivedListener(\n (notification) => {\n handler(flattenPayload(notification));\n },\n );\n return () => subscription.remove();\n },\n\n addNotificationOpenedListener(handler) {\n const subscription =\n Notifications.addNotificationResponseReceivedListener((response) => {\n handler(flattenPayload(response.notification));\n });\n return () => subscription.remove();\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA+B;AAC/B,0BAAyB;AAOzB,SAAS,kBAAqC;AAC5C,MAAI,6BAAS,OAAO,SAAS,6BAAS,OAAO,WAAW;AACtD,WAAO,6BAAS;AAAA,EAClB;AACA,SAAO;AACT;AAEA,SAAS,eACP,cACyB;AACzB,QAAM,OAAO,aAAa,QAAQ,QAAQ;AAC1C,MAAI,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,GAAG;AAC5D,WAAO,EAAE,GAAI,KAAiC;AAAA,EAChD;AACA,SAAO,CAAC;AACV;AAEA,SAAS,oBACP,QACuC;AACvC,MAAI,WAAW,WAAW;AACxB,WAAO;AAAA,EACT;AACA,MAAI,WAAW,UAAU;AACvB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,IAAM,kBAAkB,MAAY;AAAC;AAErC,SAAS,oBAAiC;AACxC,SAAO;AAAA,IACL,qBAAqB,YAAY;AAAA,IACjC,mBAAmB,YAAY;AAAA,IAC/B,UAAU,YAAY;AAAA,IACtB,iCAAiC,MAAM;AAAA,IACvC,+BAA+B,MAAM;AAAA,EACvC;AACF;AAEO,SAAS,kBAAkB,MAA0C;AAC1E,QAAM,WAAW,gBAAgB;AACjC,MAAI,CAAC,UAAU;AACb,WAAO,kBAAkB;AAAA,EAC3B;AAEA,SAAO;AAAA,IACL,MAAM,sBAAsB;AAC1B,YAAM,EAAE,OAAO,IAAI,MAAoB,kCAAoB;AAC3D,aAAO,oBAAoB,MAAM;AAAA,IACnC;AAAA,IAEA,MAAM,oBAAoB;AACxB,YAAM,EAAE,OAAO,IAAI,MAAoB,sCAAwB;AAC/D,aAAO,WAAW;AAAA,IACpB;AAAA,IAEA,MAAM,WAA6C;AACjD,YAAM,aAAa,MAAM,KAAK,oBAAoB;AAClD,UAAI,eAAe,WAAW;AAC5B,eAAO;AAAA,MACT;AAEA,UAAI;AACF,cAAM,SAAS,MAAoB,oCAAsB;AAAA,UACvD,WAAW,KAAK;AAAA,QAClB,CAAC;AACD,eAAO;AAAA,UACL,OAAO,OAAO;AAAA,UACd,UAAU;AAAA,UACV;AAAA,QACF;AAAA,MACF,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEA,gCAAgC,SAAS;AACvC,YAAM,eAA6B;AAAA,QACjC,CAAC,iBAAiB;AAChB,kBAAQ,eAAe,YAAY,CAAC;AAAA,QACtC;AAAA,MACF;AACA,aAAO,MAAM,aAAa,OAAO;AAAA,IACnC;AAAA,IAEA,8BAA8B,SAAS;AACrC,YAAM,eACU,sDAAwC,CAAC,aAAa;AAClE,gBAAQ,eAAe,SAAS,YAAY,CAAC;AAAA,MAC/C,CAAC;AACH,aAAO,MAAM,aAAa,OAAO;AAAA,IACnC;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// src/push-expo/index.ts
|
|
2
|
+
import * as Notifications from "expo-notifications";
|
|
3
|
+
import { Platform } from "react-native";
|
|
4
|
+
function resolvePlatform() {
|
|
5
|
+
if (Platform.OS === "ios" || Platform.OS === "android") {
|
|
6
|
+
return Platform.OS;
|
|
7
|
+
}
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
function flattenPayload(notification) {
|
|
11
|
+
const data = notification.request.content.data;
|
|
12
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
13
|
+
return { ...data };
|
|
14
|
+
}
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
function mapPermissionStatus(status) {
|
|
18
|
+
if (status === "granted") {
|
|
19
|
+
return "granted";
|
|
20
|
+
}
|
|
21
|
+
if (status === "denied") {
|
|
22
|
+
return "denied";
|
|
23
|
+
}
|
|
24
|
+
return "undetermined";
|
|
25
|
+
}
|
|
26
|
+
var noopUnsubscribe = () => {
|
|
27
|
+
};
|
|
28
|
+
function createNoopAdapter() {
|
|
29
|
+
return {
|
|
30
|
+
getPermissionStatus: async () => "denied",
|
|
31
|
+
requestPermission: async () => false,
|
|
32
|
+
getToken: async () => null,
|
|
33
|
+
addNotificationReceivedListener: () => noopUnsubscribe,
|
|
34
|
+
addNotificationOpenedListener: () => noopUnsubscribe
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function createExpoAdapter(opts) {
|
|
38
|
+
const platform = resolvePlatform();
|
|
39
|
+
if (!platform) {
|
|
40
|
+
return createNoopAdapter();
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
async getPermissionStatus() {
|
|
44
|
+
const { status } = await Notifications.getPermissionsAsync();
|
|
45
|
+
return mapPermissionStatus(status);
|
|
46
|
+
},
|
|
47
|
+
async requestPermission() {
|
|
48
|
+
const { status } = await Notifications.requestPermissionsAsync();
|
|
49
|
+
return status === "granted";
|
|
50
|
+
},
|
|
51
|
+
async getToken() {
|
|
52
|
+
const permission = await this.getPermissionStatus();
|
|
53
|
+
if (permission !== "granted") {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const result = await Notifications.getExpoPushTokenAsync({
|
|
58
|
+
projectId: opts.projectId
|
|
59
|
+
});
|
|
60
|
+
return {
|
|
61
|
+
token: result.data,
|
|
62
|
+
provider: "expo",
|
|
63
|
+
platform
|
|
64
|
+
};
|
|
65
|
+
} catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
addNotificationReceivedListener(handler) {
|
|
70
|
+
const subscription = Notifications.addNotificationReceivedListener(
|
|
71
|
+
(notification) => {
|
|
72
|
+
handler(flattenPayload(notification));
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
return () => subscription.remove();
|
|
76
|
+
},
|
|
77
|
+
addNotificationOpenedListener(handler) {
|
|
78
|
+
const subscription = Notifications.addNotificationResponseReceivedListener((response) => {
|
|
79
|
+
handler(flattenPayload(response.notification));
|
|
80
|
+
});
|
|
81
|
+
return () => subscription.remove();
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
createExpoAdapter
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=index.js.map
|