@clix-so/react-native-sdk 0.0.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/LICENSE +27 -0
- package/README.md +345 -0
- package/lib/module/core/Clix.js +217 -0
- package/lib/module/core/Clix.js.map +1 -0
- package/lib/module/core/ClixConfig.js +4 -0
- package/lib/module/core/ClixConfig.js.map +1 -0
- package/lib/module/core/ClixInitCoordinator.js +58 -0
- package/lib/module/core/ClixInitCoordinator.js.map +1 -0
- package/lib/module/core/ClixVersion.js +17 -0
- package/lib/module/core/ClixVersion.js.map +1 -0
- package/lib/module/index.js +7 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/models/ClixDevice.js +51 -0
- package/lib/module/models/ClixDevice.js.map +1 -0
- package/lib/module/models/ClixPushNotificationPayload.js +21 -0
- package/lib/module/models/ClixPushNotificationPayload.js.map +1 -0
- package/lib/module/models/ClixUserProperty.js +44 -0
- package/lib/module/models/ClixUserProperty.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/services/ClixAPIClient.js +172 -0
- package/lib/module/services/ClixAPIClient.js.map +1 -0
- package/lib/module/services/DeviceAPIService.js +112 -0
- package/lib/module/services/DeviceAPIService.js.map +1 -0
- package/lib/module/services/DeviceService.js +157 -0
- package/lib/module/services/DeviceService.js.map +1 -0
- package/lib/module/services/EventAPIService.js +36 -0
- package/lib/module/services/EventAPIService.js.map +1 -0
- package/lib/module/services/EventService.js +29 -0
- package/lib/module/services/EventService.js.map +1 -0
- package/lib/module/services/NotificationService.js +549 -0
- package/lib/module/services/NotificationService.js.map +1 -0
- package/lib/module/services/StorageService.js +76 -0
- package/lib/module/services/StorageService.js.map +1 -0
- package/lib/module/services/TokenService.js +71 -0
- package/lib/module/services/TokenService.js.map +1 -0
- package/lib/module/utils/ClixError.js +63 -0
- package/lib/module/utils/ClixError.js.map +1 -0
- package/lib/module/utils/UUID.js +28 -0
- package/lib/module/utils/UUID.js.map +1 -0
- package/lib/module/utils/logging/ClixLogger.js +55 -0
- package/lib/module/utils/logging/ClixLogger.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/core/Clix.d.ts +67 -0
- package/lib/typescript/src/core/Clix.d.ts.map +1 -0
- package/lib/typescript/src/core/ClixConfig.d.ts +9 -0
- package/lib/typescript/src/core/ClixConfig.d.ts.map +1 -0
- package/lib/typescript/src/core/ClixInitCoordinator.d.ts +16 -0
- package/lib/typescript/src/core/ClixInitCoordinator.d.ts.map +1 -0
- package/lib/typescript/src/core/ClixVersion.d.ts +6 -0
- package/lib/typescript/src/core/ClixVersion.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +5 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/models/ClixDevice.d.ts +42 -0
- package/lib/typescript/src/models/ClixDevice.d.ts.map +1 -0
- package/lib/typescript/src/models/ClixPushNotificationPayload.d.ts +23 -0
- package/lib/typescript/src/models/ClixPushNotificationPayload.d.ts.map +1 -0
- package/lib/typescript/src/models/ClixUserProperty.d.ts +19 -0
- package/lib/typescript/src/models/ClixUserProperty.d.ts.map +1 -0
- package/lib/typescript/src/services/ClixAPIClient.d.ts +35 -0
- package/lib/typescript/src/services/ClixAPIClient.d.ts.map +1 -0
- package/lib/typescript/src/services/DeviceAPIService.d.ts +13 -0
- package/lib/typescript/src/services/DeviceAPIService.d.ts.map +1 -0
- package/lib/typescript/src/services/DeviceService.d.ts +20 -0
- package/lib/typescript/src/services/DeviceService.d.ts.map +1 -0
- package/lib/typescript/src/services/EventAPIService.d.ts +7 -0
- package/lib/typescript/src/services/EventAPIService.d.ts.map +1 -0
- package/lib/typescript/src/services/EventService.d.ts +9 -0
- package/lib/typescript/src/services/EventService.d.ts.map +1 -0
- package/lib/typescript/src/services/NotificationService.d.ts +56 -0
- package/lib/typescript/src/services/NotificationService.d.ts.map +1 -0
- package/lib/typescript/src/services/StorageService.d.ts +10 -0
- package/lib/typescript/src/services/StorageService.d.ts.map +1 -0
- package/lib/typescript/src/services/TokenService.d.ts +15 -0
- package/lib/typescript/src/services/TokenService.d.ts.map +1 -0
- package/lib/typescript/src/utils/ClixError.d.ts +41 -0
- package/lib/typescript/src/utils/ClixError.d.ts.map +1 -0
- package/lib/typescript/src/utils/UUID.d.ts +14 -0
- package/lib/typescript/src/utils/UUID.d.ts.map +1 -0
- package/lib/typescript/src/utils/logging/ClixLogger.d.ts +18 -0
- package/lib/typescript/src/utils/logging/ClixLogger.d.ts.map +1 -0
- package/package.json +151 -0
- package/src/core/Clix.ts +256 -0
- package/src/core/ClixConfig.ts +9 -0
- package/src/core/ClixInitCoordinator.ts +65 -0
- package/src/core/ClixVersion.ts +17 -0
- package/src/index.ts +5 -0
- package/src/models/ClixDevice.ts +88 -0
- package/src/models/ClixPushNotificationPayload.ts +38 -0
- package/src/models/ClixUserProperty.ts +58 -0
- package/src/services/ClixAPIClient.ts +248 -0
- package/src/services/DeviceAPIService.ts +187 -0
- package/src/services/DeviceService.ts +204 -0
- package/src/services/EventAPIService.ts +48 -0
- package/src/services/EventService.ts +45 -0
- package/src/services/NotificationService.ts +730 -0
- package/src/services/StorageService.ts +84 -0
- package/src/services/TokenService.ts +84 -0
- package/src/utils/ClixError.ts +78 -0
- package/src/utils/UUID.ts +29 -0
- package/src/utils/logging/ClixLogger.ts +61 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { MMKV } from 'react-native-mmkv';
|
|
2
|
+
import { ClixLogger } from '../utils/logging/ClixLogger';
|
|
3
|
+
|
|
4
|
+
export class StorageService {
|
|
5
|
+
private storage: MMKV;
|
|
6
|
+
|
|
7
|
+
constructor() {
|
|
8
|
+
this.storage = new MMKV({
|
|
9
|
+
id: 'clix-storage',
|
|
10
|
+
encryptionKey: undefined, // Add encryption if needed
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async set<T>(key: string, value: T): Promise<void> {
|
|
15
|
+
if (value === undefined) {
|
|
16
|
+
try {
|
|
17
|
+
this.storage.delete(key);
|
|
18
|
+
} catch (error) {
|
|
19
|
+
ClixLogger.error(`Failed to remove value for key: ${key}`, error);
|
|
20
|
+
}
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const encoded = JSON.stringify(value);
|
|
26
|
+
this.storage.set(key, encoded);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
ClixLogger.error(`Failed to set value for key: ${key}`, error);
|
|
29
|
+
// Don't throw storage errors to prevent initialization failure
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async get<T>(key: string): Promise<T | undefined> {
|
|
35
|
+
try {
|
|
36
|
+
const data = this.storage.getString(key);
|
|
37
|
+
if (data === null || data === undefined) return undefined;
|
|
38
|
+
try {
|
|
39
|
+
const decoded = JSON.parse(data);
|
|
40
|
+
return decoded as T;
|
|
41
|
+
} catch (jsonError) {
|
|
42
|
+
// Handle legacy string values
|
|
43
|
+
ClixLogger.debug(
|
|
44
|
+
`Found legacy string value for key: ${key}, migrating to JSON format`
|
|
45
|
+
);
|
|
46
|
+
await this.set(key, data);
|
|
47
|
+
return data as T;
|
|
48
|
+
}
|
|
49
|
+
} catch (error) {
|
|
50
|
+
ClixLogger.error(`Failed to get value for key: ${key}`, error);
|
|
51
|
+
// Return undefined instead of throwing to prevent initialization failure
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async remove(key: string): Promise<void> {
|
|
57
|
+
try {
|
|
58
|
+
this.storage.delete(key);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
ClixLogger.error(`Failed to remove key: ${key}`, error);
|
|
61
|
+
// Don't throw to prevent initialization failure
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async clear(): Promise<void> {
|
|
67
|
+
try {
|
|
68
|
+
this.storage.clearAll();
|
|
69
|
+
} catch (error) {
|
|
70
|
+
ClixLogger.error('Failed to clear storage', error);
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async getAllKeys(): Promise<string[]> {
|
|
76
|
+
try {
|
|
77
|
+
const keys = this.storage.getAllKeys();
|
|
78
|
+
return Array.from(keys);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
ClixLogger.error('Failed to get all keys', error);
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ClixLogger } from '../utils/logging/ClixLogger';
|
|
2
|
+
import { StorageService } from './StorageService';
|
|
3
|
+
|
|
4
|
+
export class TokenService {
|
|
5
|
+
private static readonly CURRENT_TOKEN_KEY = 'clix_current_push_token';
|
|
6
|
+
private static readonly PREVIOUS_TOKENS_KEY = 'clix_push_tokens';
|
|
7
|
+
private static readonly MAX_TOKENS = 5;
|
|
8
|
+
|
|
9
|
+
constructor(private readonly storageService: StorageService) {}
|
|
10
|
+
|
|
11
|
+
async getCurrentToken(): Promise<string | undefined> {
|
|
12
|
+
try {
|
|
13
|
+
return await this.storageService.get<string>(
|
|
14
|
+
TokenService.CURRENT_TOKEN_KEY
|
|
15
|
+
);
|
|
16
|
+
} catch (error) {
|
|
17
|
+
ClixLogger.error('Failed to get current token', error);
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async getPreviousTokens(): Promise<string[]> {
|
|
23
|
+
try {
|
|
24
|
+
const result = await this.storageService.get<string[]>(
|
|
25
|
+
TokenService.PREVIOUS_TOKENS_KEY
|
|
26
|
+
);
|
|
27
|
+
if (result === undefined) return [];
|
|
28
|
+
|
|
29
|
+
return Array.isArray(result) ? result : [];
|
|
30
|
+
} catch (error) {
|
|
31
|
+
ClixLogger.error('Failed to get previous tokens', error);
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async saveToken(token: string): Promise<void> {
|
|
37
|
+
try {
|
|
38
|
+
await this.storageService.set(TokenService.CURRENT_TOKEN_KEY, token);
|
|
39
|
+
|
|
40
|
+
let tokens = await this.getPreviousTokens();
|
|
41
|
+
|
|
42
|
+
// Remove existing token if present
|
|
43
|
+
const currentIndex = tokens.indexOf(token);
|
|
44
|
+
if (currentIndex !== -1) {
|
|
45
|
+
tokens.splice(currentIndex, 1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Add new token
|
|
49
|
+
tokens.push(token);
|
|
50
|
+
|
|
51
|
+
// Keep only the last MAX_TOKENS
|
|
52
|
+
if (tokens.length > TokenService.MAX_TOKENS) {
|
|
53
|
+
tokens = tokens.slice(-TokenService.MAX_TOKENS);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
await this.storageService.set(TokenService.PREVIOUS_TOKENS_KEY, tokens);
|
|
57
|
+
ClixLogger.debug('Token saved successfully');
|
|
58
|
+
} catch (error) {
|
|
59
|
+
ClixLogger.error('Failed to save token', error);
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async clearTokens(): Promise<void> {
|
|
65
|
+
try {
|
|
66
|
+
await this.storageService.remove(TokenService.PREVIOUS_TOKENS_KEY);
|
|
67
|
+
await this.storageService.remove(TokenService.CURRENT_TOKEN_KEY);
|
|
68
|
+
ClixLogger.debug('All tokens cleared');
|
|
69
|
+
} catch (error) {
|
|
70
|
+
ClixLogger.error('Failed to clear tokens', error);
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
convertTokenToString(deviceToken: number[]): string {
|
|
76
|
+
return deviceToken
|
|
77
|
+
.map((data) => data.toString(16).padStart(2, '0'))
|
|
78
|
+
.join('');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async reset(): Promise<void> {
|
|
82
|
+
await this.clearTokens();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export enum ClixErrorCode {
|
|
2
|
+
NOT_INITIALIZED = 'NOT_INITIALIZED',
|
|
3
|
+
INVALID_CONFIGURATION = 'INVALID_CONFIGURATION',
|
|
4
|
+
INVALID_URL = 'INVALID_URL',
|
|
5
|
+
INVALID_RESPONSE = 'INVALID_RESPONSE',
|
|
6
|
+
ENCODING_ERROR = 'ENCODING_ERROR',
|
|
7
|
+
DECODING_ERROR = 'DECODING_ERROR',
|
|
8
|
+
NETWORK_ERROR = 'NETWORK_ERROR',
|
|
9
|
+
UNKNOWN_ERROR = 'UNKNOWN_ERROR',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const ClixErrorMessages: Record<ClixErrorCode, string> = {
|
|
13
|
+
[ClixErrorCode.NOT_INITIALIZED]:
|
|
14
|
+
'Clix SDK is not initialized. Call Clix.initialize() first.',
|
|
15
|
+
[ClixErrorCode.INVALID_CONFIGURATION]: 'Invalid SDK configuration.',
|
|
16
|
+
[ClixErrorCode.INVALID_URL]: 'The provided URL is invalid.',
|
|
17
|
+
[ClixErrorCode.INVALID_RESPONSE]:
|
|
18
|
+
'The response was invalid or permission was denied.',
|
|
19
|
+
[ClixErrorCode.ENCODING_ERROR]: 'Failed to encode request body.',
|
|
20
|
+
[ClixErrorCode.DECODING_ERROR]: 'Failed to decode response body.',
|
|
21
|
+
[ClixErrorCode.NETWORK_ERROR]: 'Network request failed.',
|
|
22
|
+
[ClixErrorCode.UNKNOWN_ERROR]: 'An unknown error occurred.',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export class ClixError extends Error {
|
|
26
|
+
readonly code: ClixErrorCode;
|
|
27
|
+
override cause?: unknown;
|
|
28
|
+
|
|
29
|
+
constructor(
|
|
30
|
+
code: ClixErrorCode,
|
|
31
|
+
message?: string,
|
|
32
|
+
options?: { cause?: unknown }
|
|
33
|
+
) {
|
|
34
|
+
super(message ?? ClixErrorMessages[code]);
|
|
35
|
+
this.name = 'ClixError';
|
|
36
|
+
this.code = code;
|
|
37
|
+
if (options?.cause) {
|
|
38
|
+
this.cause = options.cause;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static notInitialized(options?: { cause?: unknown }) {
|
|
43
|
+
return new ClixError(ClixErrorCode.NOT_INITIALIZED, undefined, options);
|
|
44
|
+
}
|
|
45
|
+
static invalidConfiguration(options?: { cause?: unknown }) {
|
|
46
|
+
return new ClixError(
|
|
47
|
+
ClixErrorCode.INVALID_CONFIGURATION,
|
|
48
|
+
undefined,
|
|
49
|
+
options
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
static invalidURL(options?: { cause?: unknown }) {
|
|
53
|
+
return new ClixError(ClixErrorCode.INVALID_URL, undefined, options);
|
|
54
|
+
}
|
|
55
|
+
static invalidResponse(options?: { cause?: unknown }) {
|
|
56
|
+
return new ClixError(ClixErrorCode.INVALID_RESPONSE, undefined, options);
|
|
57
|
+
}
|
|
58
|
+
static encodingError(options?: { cause?: unknown }) {
|
|
59
|
+
return new ClixError(ClixErrorCode.ENCODING_ERROR, undefined, options);
|
|
60
|
+
}
|
|
61
|
+
static decodingError(options?: { cause?: unknown }) {
|
|
62
|
+
return new ClixError(ClixErrorCode.DECODING_ERROR, undefined, options);
|
|
63
|
+
}
|
|
64
|
+
static networkError(underlyingError: unknown) {
|
|
65
|
+
return new ClixError(ClixErrorCode.NETWORK_ERROR, undefined, {
|
|
66
|
+
cause: underlyingError,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
static unknownError(options?: { cause?: unknown; reason?: string }) {
|
|
70
|
+
const msg =
|
|
71
|
+
options?.reason != null
|
|
72
|
+
? `${ClixErrorMessages[ClixErrorCode.UNKNOWN_ERROR]}: ${options.reason}`
|
|
73
|
+
: undefined;
|
|
74
|
+
return new ClixError(ClixErrorCode.UNKNOWN_ERROR, msg, {
|
|
75
|
+
cause: options?.cause,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import 'react-native-get-random-values';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
import { ClixLogger } from './logging/ClixLogger';
|
|
4
|
+
|
|
5
|
+
export class UUID {
|
|
6
|
+
/**
|
|
7
|
+
* Generates a new UUID v4
|
|
8
|
+
* @returns A new UUID string
|
|
9
|
+
*/
|
|
10
|
+
static generate(): string {
|
|
11
|
+
try {
|
|
12
|
+
return uuidv4();
|
|
13
|
+
} catch (error) {
|
|
14
|
+
ClixLogger.warn(
|
|
15
|
+
'UUID generation failed, using fallback ID generation',
|
|
16
|
+
error
|
|
17
|
+
);
|
|
18
|
+
return this.generateFallbackId();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Generates a fallback ID when UUID generation fails
|
|
24
|
+
* @returns A fallback ID string
|
|
25
|
+
*/
|
|
26
|
+
private static generateFallbackId(): string {
|
|
27
|
+
return `clix_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export enum ClixLogLevel {
|
|
2
|
+
NONE = 0,
|
|
3
|
+
ERROR = 1,
|
|
4
|
+
WARN = 2,
|
|
5
|
+
INFO = 3,
|
|
6
|
+
DEBUG = 4,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class ClixLogger {
|
|
10
|
+
private static logLevel: ClixLogLevel = ClixLogLevel.INFO;
|
|
11
|
+
|
|
12
|
+
static setLogLevel(level: ClixLogLevel): void {
|
|
13
|
+
this.logLevel = level;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static shouldLog(level: ClixLogLevel): boolean {
|
|
17
|
+
return this.logLevel >= level;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static log(level: ClixLogLevel, message: string, error?: any): void {
|
|
21
|
+
if (level > this.logLevel) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const timestamp = new Date().toISOString();
|
|
26
|
+
const messages = [`[Clix][${timestamp}] ${message}`, error].filter(Boolean);
|
|
27
|
+
|
|
28
|
+
switch (level) {
|
|
29
|
+
case ClixLogLevel.DEBUG:
|
|
30
|
+
console.debug(...messages);
|
|
31
|
+
break;
|
|
32
|
+
case ClixLogLevel.INFO:
|
|
33
|
+
console.info(...messages);
|
|
34
|
+
break;
|
|
35
|
+
case ClixLogLevel.WARN:
|
|
36
|
+
console.warn(...messages);
|
|
37
|
+
break;
|
|
38
|
+
case ClixLogLevel.ERROR:
|
|
39
|
+
console.error(...messages);
|
|
40
|
+
break;
|
|
41
|
+
case ClixLogLevel.NONE:
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static error(message: string, error?: any): void {
|
|
47
|
+
this.log(ClixLogLevel.ERROR, message, error);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static warn(message: string, error?: any): void {
|
|
51
|
+
this.log(ClixLogLevel.WARN, message, error);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static info(message: string, error?: any): void {
|
|
55
|
+
this.log(ClixLogLevel.INFO, message, error);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static debug(message: string, error?: any): void {
|
|
59
|
+
this.log(ClixLogLevel.DEBUG, message, error);
|
|
60
|
+
}
|
|
61
|
+
}
|