@ordersune/crm-web-sdk 1.0.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/LICENSE ADDED
@@ -0,0 +1 @@
1
+ MIT License
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # Order Sune CRM TypeScript SDK
2
+
3
+ A powerful TypeScript SDK for integrating the Order Sune CRM solution into your web applications. Enables seamless user tracking, event monitoring, and customer data management.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @ordersune/crm-web-sdk
9
+ # or
10
+ yarn add @ordersune/crm-web-sdk
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ### Initialize the SDK
16
+
17
+ ```typescript
18
+ import { WebSDK } from '@ordersune/crm-web-sdk';
19
+
20
+ const crm = new WebSDK({
21
+ apiKey: 'your-api-key',
22
+ endpoint: 'https://api.example.com',
23
+ debug: false
24
+ });
25
+ ```
26
+
27
+ ### User Identification
28
+
29
+ Identify and track users with custom traits:
30
+
31
+ ```typescript
32
+ // Identify a registered user
33
+ crm.identify('user123', {
34
+ email: 'user@example.com',
35
+ name: 'John Doe',
36
+ subscription: 'premium'
37
+ });
38
+
39
+ // Get current user profile
40
+ const userProfile = crm.getUserProfile();
41
+ ```
42
+
43
+ ### Event Tracking
44
+
45
+ Track user events with custom properties:
46
+
47
+ ```typescript
48
+ // Basic event tracking
49
+ crm.trackEvent('page_view');
50
+
51
+ // Event with properties
52
+ crm.trackEvent('purchase_completed', {
53
+ productId: 'prod_123',
54
+ amount: 99.99,
55
+ currency: 'USD'
56
+ });
57
+
58
+ // Event with custom options
59
+ crm.trackEvent('custom_event',
60
+ { key: 'value' },
61
+ {
62
+ timestamp: '2024-12-28T10:00:00Z',
63
+ requestId: 'req_abc123'
64
+ }
65
+ );
66
+ ```
67
+
68
+ ### Custom Attributes
69
+
70
+ Track persistent user attributes:
71
+
72
+ ```typescript
73
+ crm.trackCustomAttribute('preference_theme', 'dark');
74
+ crm.trackCustomAttribute('notification_enabled', true);
75
+ ```
76
+
77
+ ## Types
78
+
79
+ ### SDKConfig
80
+
81
+ ```typescript
82
+ interface SDKConfig {
83
+ apiKey: string; // Your API key
84
+ endpoint: string; // API endpoint URL
85
+ debug?: boolean; // Enable debug logging
86
+ }
87
+ ```
88
+
89
+ ### UserProfile
90
+
91
+ ```typescript
92
+ interface UserProfile {
93
+ id: string; // User identifier
94
+ user_type: string; // 'registered' or 'guest'
95
+ traits: Record<string, any>; // Custom user traits
96
+ }
97
+ ```
98
+
99
+ ### EventOptions
100
+
101
+ ```typescript
102
+ interface EventOptions {
103
+ timestamp?: string; // Custom event timestamp
104
+ requestId?: string; // Custom request identifier
105
+ }
106
+ ```
107
+
108
+ ## Features
109
+
110
+ - Automatic session tracking
111
+ - Device and browser detection
112
+ - Batch event processing
113
+ - Offline event queuing
114
+ - TypeScript support with full type definitions
115
+ - Debug mode for development
116
+
117
+ ## Requirements
118
+
119
+ - TypeScript 5.0+
120
+ - Modern browser environment with localStorage support
121
+ - Stable internet connection for event sending
122
+
123
+ ## License
124
+
125
+ MIT License
126
+
127
+ For detailed API documentation and examples, visit our [documentation site](https://docs.ordersune.com/crm).
128
+
129
+ ---
130
+
131
+ Need help? [Contact Support](mailto:support@ordersune.com)
@@ -0,0 +1,2 @@
1
+ export { WebSDK } from "./web-sdk";
2
+ export type { SDKConfig, EventOptions, UserProfile } from "./types";
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebSDK = void 0;
4
+ var web_sdk_1 = require("./web-sdk");
5
+ Object.defineProperty(exports, "WebSDK", { enumerable: true, get: function () { return web_sdk_1.WebSDK; } });
@@ -0,0 +1,14 @@
1
+ export interface UserProfile {
2
+ id: string;
3
+ user_type: string;
4
+ traits: Record<string, any>;
5
+ }
6
+ export interface EventOptions {
7
+ timestamp?: string;
8
+ requestId?: string;
9
+ }
10
+ export interface SDKConfig {
11
+ apiKey: string;
12
+ endpoint: string;
13
+ debug?: boolean;
14
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export declare const log: (debug: boolean, message: string, ...args: any[]) => void;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.log = void 0;
4
+ const log = (debug, message, ...args) => {
5
+ if (debug) {
6
+ console.log(`[OrderSune CRM]`, message, ...args);
7
+ }
8
+ };
9
+ exports.log = log;
@@ -0,0 +1,32 @@
1
+ import { SDKConfig, EventOptions, UserProfile } from "./types";
2
+ export declare class WebSDK {
3
+ private readonly apiKey;
4
+ private readonly endpoint;
5
+ private readonly debug;
6
+ private readonly maxBatchSize;
7
+ private readonly batchInterval;
8
+ private readonly sdkVersion;
9
+ private deviceId;
10
+ private deviceDetails?;
11
+ private currentUser?;
12
+ private eventQueue;
13
+ private isProcessingQueue;
14
+ private customAttributes;
15
+ constructor(config: SDKConfig);
16
+ identify(userId: string, traits?: Record<string, any>): void;
17
+ trackEvent(eventName: string, properties?: Record<string, any>, options?: EventOptions): void;
18
+ trackCustomAttribute(attributeName: string, attributeValue: any): void;
19
+ getUserProfile(): UserProfile | undefined;
20
+ private initialize;
21
+ private getStoredDeviceId;
22
+ private storeDeviceId;
23
+ private getGuestUserId;
24
+ private initializeDeviceDetails;
25
+ private detectDeviceType;
26
+ private detectBrowserType;
27
+ private detectBrowserVersion;
28
+ private startBatchProcessing;
29
+ private queueEvent;
30
+ private processBatch;
31
+ private sendBatchToServer;
32
+ }
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebSDK = void 0;
4
+ const utils_1 = require("./utils");
5
+ const uuid_1 = require("uuid");
6
+ const STORAGE_PREFIX = "os.";
7
+ const DEFAULT_BATCH_SIZE = 10;
8
+ const DEFAULT_BATCH_INTERVAL = 10000;
9
+ const SDK_VERSION = "1.0.6";
10
+ class WebSDK {
11
+ constructor(config) {
12
+ var _a;
13
+ this.maxBatchSize = DEFAULT_BATCH_SIZE;
14
+ this.batchInterval = DEFAULT_BATCH_INTERVAL;
15
+ this.sdkVersion = SDK_VERSION;
16
+ this.eventQueue = [];
17
+ this.isProcessingQueue = false;
18
+ this.customAttributes = {};
19
+ this.apiKey = config.apiKey;
20
+ this.endpoint = config.endpoint;
21
+ this.debug = (_a = config.debug) !== null && _a !== void 0 ? _a : false;
22
+ this.deviceId = this.getStoredDeviceId() || (0, uuid_1.v4)();
23
+ this.initialize();
24
+ }
25
+ identify(userId, traits = {}) {
26
+ var _a;
27
+ this.currentUser = {
28
+ id: userId || this.getGuestUserId(),
29
+ user_type: userId ? "registered" : "guest",
30
+ traits: { ...(_a = this.currentUser) === null || _a === void 0 ? void 0 : _a.traits, ...traits },
31
+ };
32
+ this.trackEvent("user_identified", {
33
+ user_id: this.currentUser.id,
34
+ traits,
35
+ });
36
+ }
37
+ trackEvent(eventName, properties = {}, options = {}) {
38
+ const payload = {
39
+ deviceId: this.deviceId,
40
+ eventName,
41
+ timestamp: options.timestamp || Date.now(),
42
+ requestId: options.requestId || (0, uuid_1.v4)(),
43
+ properties,
44
+ };
45
+ this.queueEvent(payload);
46
+ }
47
+ trackCustomAttribute(attributeName, attributeValue) {
48
+ this.customAttributes[attributeName] = attributeValue;
49
+ }
50
+ getUserProfile() {
51
+ return this.currentUser;
52
+ }
53
+ initialize() {
54
+ this.storeDeviceId();
55
+ this.initializeDeviceDetails();
56
+ this.identify("");
57
+ this.startBatchProcessing();
58
+ (0, utils_1.log)(this.debug, "SDK Initialized");
59
+ }
60
+ getStoredDeviceId() {
61
+ return localStorage.getItem(`${STORAGE_PREFIX}${this.apiKey}.device_id`);
62
+ }
63
+ storeDeviceId() {
64
+ localStorage.setItem(`${STORAGE_PREFIX}${this.apiKey}.device_id`, this.deviceId);
65
+ }
66
+ getGuestUserId() {
67
+ return `guest_user_${this.deviceId}`;
68
+ }
69
+ async initializeDeviceDetails() {
70
+ this.deviceDetails = {
71
+ deviceModel: await this.detectDeviceType(),
72
+ browser: this.detectBrowserType(),
73
+ browserVersion: this.detectBrowserVersion(),
74
+ };
75
+ }
76
+ async detectDeviceType() {
77
+ if ("userAgentData" in navigator) {
78
+ try {
79
+ const data = await navigator.userAgentData.getHighEntropyValues(["platform", "mobile"]);
80
+ if (data.mobile) {
81
+ return data.platform.toLowerCase().includes("ios")
82
+ ? "ios"
83
+ : "android";
84
+ }
85
+ const platform = data.platform.toLowerCase();
86
+ if (platform.includes("mac"))
87
+ return "mac";
88
+ if (platform.includes("win"))
89
+ return "windows";
90
+ if (platform.includes("linux"))
91
+ return "linux";
92
+ }
93
+ catch (error) {
94
+ (0, utils_1.log)(this.debug, "Client Hints API failed", error);
95
+ }
96
+ }
97
+ const userAgent = navigator.userAgent.toLowerCase();
98
+ if (/iphone|ipad|ipod/.test(userAgent))
99
+ return "ios";
100
+ if (/android/.test(userAgent))
101
+ return "android";
102
+ if (/macintosh|mac os x/.test(userAgent))
103
+ return "mac";
104
+ if (/windows|win32|win64/.test(userAgent))
105
+ return "windows";
106
+ if (/linux/.test(userAgent))
107
+ return "linux";
108
+ return "unknown";
109
+ }
110
+ detectBrowserType() {
111
+ if ("userAgentData" in navigator) {
112
+ try {
113
+ const brands = navigator.userAgentData.brands;
114
+ const brand = brands.find((b) => !["Chrome HTML", "Chromium", "Not A(Brand"].includes(b.brand));
115
+ if (brand)
116
+ return brand.brand.toLowerCase();
117
+ }
118
+ catch (error) {
119
+ (0, utils_1.log)(this.debug, "Browser detection failed", error);
120
+ }
121
+ }
122
+ const userAgent = navigator.userAgent.toLowerCase();
123
+ if (/edg\//.test(userAgent))
124
+ return "edge";
125
+ if (/chrome/.test(userAgent) && !/edg\//.test(userAgent))
126
+ return "chrome";
127
+ if (/firefox/.test(userAgent))
128
+ return "firefox";
129
+ if (/safari/.test(userAgent) && !/chrome/.test(userAgent))
130
+ return "safari";
131
+ return "unknown";
132
+ }
133
+ detectBrowserVersion() {
134
+ if ("userAgentData" in navigator) {
135
+ try {
136
+ const brands = navigator.userAgentData.brands;
137
+ const brand = brands.find((b) => !["Chrome HTML", "Chromium", "Not A(Brand"].includes(b.brand));
138
+ if (brand)
139
+ return brand.version;
140
+ }
141
+ catch (error) {
142
+ (0, utils_1.log)(this.debug, "Browser version detection failed", error);
143
+ }
144
+ }
145
+ const userAgent = navigator.userAgent.toLowerCase();
146
+ const browserPatterns = {
147
+ chrome: /chrome\/(\d+)/,
148
+ firefox: /firefox\/(\d+)/,
149
+ safari: /version\/(\d+)/,
150
+ edge: /edg\/(\d+)/,
151
+ };
152
+ const browserType = this.detectBrowserType();
153
+ const pattern = browserPatterns[browserType];
154
+ if (!pattern)
155
+ return "unknown";
156
+ const match = userAgent.match(pattern);
157
+ return match ? match[1] : "unknown";
158
+ }
159
+ startBatchProcessing() {
160
+ setInterval(() => {
161
+ if (this.eventQueue.length > 0) {
162
+ this.processBatch();
163
+ }
164
+ }, this.batchInterval);
165
+ }
166
+ queueEvent(payload) {
167
+ this.eventQueue.push(payload);
168
+ (0, utils_1.log)(this.debug, "Event queued", payload);
169
+ if (this.eventQueue.length >= this.maxBatchSize) {
170
+ this.processBatch();
171
+ }
172
+ }
173
+ async processBatch() {
174
+ if (this.isProcessingQueue)
175
+ return;
176
+ this.isProcessingQueue = true;
177
+ const batchToSend = this.eventQueue.splice(0, this.maxBatchSize);
178
+ try {
179
+ await this.sendBatchToServer(batchToSend);
180
+ }
181
+ catch (error) {
182
+ this.eventQueue.unshift(...batchToSend);
183
+ (0, utils_1.log)(this.debug, "Batch processing failed", error);
184
+ }
185
+ finally {
186
+ this.isProcessingQueue = false;
187
+ }
188
+ }
189
+ async sendBatchToServer(batch) {
190
+ var _a;
191
+ const payload = {
192
+ sdkVersion: this.sdkVersion,
193
+ deviceInfo: this.deviceDetails,
194
+ userId: (_a = this.currentUser) === null || _a === void 0 ? void 0 : _a.id,
195
+ events: batch,
196
+ userAttributes: this.customAttributes,
197
+ };
198
+ try {
199
+ const response = await fetch(`${this.endpoint}/analytics/data`, {
200
+ method: "POST",
201
+ headers: {
202
+ "Content-Type": "application/json",
203
+ "x-api-key": this.apiKey,
204
+ },
205
+ body: JSON.stringify(payload),
206
+ });
207
+ if (!response.ok) {
208
+ throw new Error(`HTTP error! status: ${response.status}`);
209
+ }
210
+ await response.json();
211
+ }
212
+ catch (error) {
213
+ (0, utils_1.log)(this.debug, "Failed to send batch to server", error);
214
+ throw error;
215
+ }
216
+ }
217
+ }
218
+ exports.WebSDK = WebSDK;
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@ordersune/crm-web-sdk",
3
+ "version": "1.0.6",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "prepare": "npm run build"
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "README.md"
16
+ ],
17
+ "dependencies": {
18
+ "uuid": "^11.0.3"
19
+ },
20
+ "devDependencies": {
21
+ "typescript": "^5.0.0",
22
+ "@types/uuid": "^9.0.0"
23
+ }
24
+ }