@savant-realms/sentinel-analytics-realm 0.0.3
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 +251 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.js +177 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# Sentinel Analytics Realm - TypeScript/JavaScript SDK
|
|
2
|
+
|
|
3
|
+
TypeScript/JavaScript SDK for the Sentinel Analytics Realm analytics platform. Works in both Node.js and browser environments.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @savant-realms/sentinel-analytics-realm
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
or
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
yarn add @savant-realms/sentinel-analytics-realm
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Basic Setup
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { SentinelAnalyticsRealmPlugin } from '@savant-realms/sentinel-analytics-realm';
|
|
23
|
+
|
|
24
|
+
const analytics = new SentinelAnalyticsRealmPlugin({
|
|
25
|
+
projectId: 'your-project-id',
|
|
26
|
+
appId: 'your-app-id',
|
|
27
|
+
env: 'prod', // or 'dev', 'staging'
|
|
28
|
+
accessToken: 'your-access-token', // optional
|
|
29
|
+
baseUrl: 'https://api.sentinelanalyticsrealm.com', // optional, defaults to this
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Environment Variables (Node.js only)
|
|
34
|
+
|
|
35
|
+
You can also configure the SDK using environment variables:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
export SENTINEL_ANALYTICS_REALM_PROJECT_ID="your-project-id"
|
|
39
|
+
export SENTINEL_ANALYTICS_REALM_APP_ID="your-app-id"
|
|
40
|
+
export SENTINEL_ANALYTICS_REALM_ENV="prod"
|
|
41
|
+
export SENTINEL_ANALYTICS_REALM_URL="https://api.sentinelanalyticsrealm.com"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Then initialize without parameters:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
const analytics = new SentinelAnalyticsRealmPlugin();
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Tracking Events
|
|
51
|
+
|
|
52
|
+
#### Single Event
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
await analytics.track('page_view', {
|
|
56
|
+
visitorId: 'visitor-123',
|
|
57
|
+
userId: 'user-456',
|
|
58
|
+
sessionId: 'session-789',
|
|
59
|
+
category: 'navigation',
|
|
60
|
+
action: 'view',
|
|
61
|
+
label: 'Home Page',
|
|
62
|
+
properties: {
|
|
63
|
+
path: '/home',
|
|
64
|
+
referrer: 'https://example.com',
|
|
65
|
+
},
|
|
66
|
+
context: {
|
|
67
|
+
userAgent: navigator.userAgent,
|
|
68
|
+
screenWidth: window.screen.width,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### Batch Events
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
await analytics.trackBatch([
|
|
77
|
+
{
|
|
78
|
+
name: 'page_view',
|
|
79
|
+
visitorId: 'visitor-123',
|
|
80
|
+
properties: { path: '/home' },
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: 'button_click',
|
|
84
|
+
visitorId: 'visitor-123',
|
|
85
|
+
properties: { button: 'signup' },
|
|
86
|
+
},
|
|
87
|
+
]);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Identity Linking
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
await analytics.identify('user-456', 'visitor-123', {
|
|
94
|
+
email: 'user@example.com',
|
|
95
|
+
name: 'John Doe',
|
|
96
|
+
plan: 'premium',
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### JavaScript (CommonJS)
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
const { SentinelAnalyticsRealmPlugin } = require('@savant-realms/sentinel-analytics-realm');
|
|
104
|
+
|
|
105
|
+
const analytics = new SentinelAnalyticsRealmPlugin({
|
|
106
|
+
projectId: 'your-project-id',
|
|
107
|
+
appId: 'your-app-id',
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
analytics.track('page_view', {
|
|
111
|
+
visitorId: 'visitor-123',
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Browser Usage
|
|
116
|
+
|
|
117
|
+
For browser usage, you'll need a bundler like Webpack, Vite, or Rollup that supports CommonJS modules, or use a CDN that provides ES modules.
|
|
118
|
+
|
|
119
|
+
Alternatively, you can use a bundler to create a browser-compatible build:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
// In your bundler configuration, ensure the SDK is included
|
|
123
|
+
import { SentinelAnalyticsRealmPlugin } from '@savant-realms/sentinel-analytics-realm';
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## API Reference
|
|
127
|
+
|
|
128
|
+
### `SentinelAnalyticsRealmPlugin`
|
|
129
|
+
|
|
130
|
+
Main class for interacting with the Sentinel Analytics Realm API.
|
|
131
|
+
|
|
132
|
+
#### Constructor
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
new SentinelAnalyticsRealmPlugin(config?: SentinelAnalyticsRealmConfig)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Config Options:**
|
|
139
|
+
|
|
140
|
+
- `projectId?: string` - Your project ID
|
|
141
|
+
- `appId?: string` - Your application ID
|
|
142
|
+
- `env?: string` - Environment ('prod', 'dev', 'staging'), defaults to 'prod'
|
|
143
|
+
- `accessToken?: string` - Optional access token for authentication
|
|
144
|
+
- `baseUrl?: string` - API base URL, defaults to '<https://api.sentinelanalyticsrealm.com>'
|
|
145
|
+
|
|
146
|
+
#### Methods
|
|
147
|
+
|
|
148
|
+
##### `track(name, eventData?, timeout?)`
|
|
149
|
+
|
|
150
|
+
Track a single event.
|
|
151
|
+
|
|
152
|
+
- `name: string` - Event name (required)
|
|
153
|
+
- `eventData?: EventData` - Event data object
|
|
154
|
+
- `timeout?: number` - Request timeout in milliseconds (default: 5000)
|
|
155
|
+
- Returns: `Promise<ApiResponse | null>`
|
|
156
|
+
|
|
157
|
+
##### `trackBatch(events, timeout?)`
|
|
158
|
+
|
|
159
|
+
Track multiple events in one call.
|
|
160
|
+
|
|
161
|
+
- `events: EventData[]` - Array of event data objects
|
|
162
|
+
- `timeout?: number` - Request timeout in milliseconds (default: 10000)
|
|
163
|
+
- Returns: `Promise<ApiResponse | null>`
|
|
164
|
+
|
|
165
|
+
##### `identify(userId, visitorId?, traits?)`
|
|
166
|
+
|
|
167
|
+
Convenience method for identity linking.
|
|
168
|
+
|
|
169
|
+
- `userId: string` - User ID (required)
|
|
170
|
+
- `visitorId?: string` - Visitor ID (optional)
|
|
171
|
+
- `traits?: Record<string, any>` - User traits/properties
|
|
172
|
+
- Returns: `Promise<ApiResponse | null>`
|
|
173
|
+
|
|
174
|
+
### EventData Interface
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
interface EventData {
|
|
178
|
+
name: string;
|
|
179
|
+
visitorId?: string;
|
|
180
|
+
userId?: string;
|
|
181
|
+
sessionId?: string;
|
|
182
|
+
category?: string;
|
|
183
|
+
action?: string;
|
|
184
|
+
label?: string;
|
|
185
|
+
value?: number;
|
|
186
|
+
properties?: Record<string, any>;
|
|
187
|
+
context?: Record<string, any>;
|
|
188
|
+
origin?: string; // 'real' or 'seed', defaults to 'real'
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Error Handling
|
|
193
|
+
|
|
194
|
+
The SDK follows a fail-silent approach similar to the Python SDK. If an error occurs during tracking, the methods return `null` instead of throwing an exception. This ensures your application continues to function even if analytics tracking fails.
|
|
195
|
+
|
|
196
|
+
## TypeScript Support
|
|
197
|
+
|
|
198
|
+
This package includes full TypeScript type definitions. No additional `@types` package is required.
|
|
199
|
+
|
|
200
|
+
## Development
|
|
201
|
+
|
|
202
|
+
### Building
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
npm install
|
|
206
|
+
npm run build
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Testing
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
npm test
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Deployment
|
|
216
|
+
|
|
217
|
+
To publish the package to npm, use the deployment script:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# Set your npm token (or add to .env file)
|
|
221
|
+
export NPM_TOKEN=your_npm_token_here
|
|
222
|
+
|
|
223
|
+
# Run deployment (builds, tests, and publishes)
|
|
224
|
+
./scripts/deploy.sh
|
|
225
|
+
|
|
226
|
+
# Or run in dry-run mode (builds and validates, but doesn't publish)
|
|
227
|
+
DRY_RUN=true ./scripts/deploy.sh
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The deployment script will:
|
|
231
|
+
1. Install dependencies
|
|
232
|
+
2. Build the TypeScript package
|
|
233
|
+
3. Run tests (if configured)
|
|
234
|
+
4. Validate package.json
|
|
235
|
+
5. Publish to npm (if `NPM_TOKEN` is set)
|
|
236
|
+
6. Optionally publish to GitLab Package Registry (if `GITLAB_NPM_TOKEN` and `CI_PROJECT_URL` are set)
|
|
237
|
+
|
|
238
|
+
You can also publish manually:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
npm run build
|
|
242
|
+
npm publish
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## License
|
|
246
|
+
|
|
247
|
+
MIT
|
|
248
|
+
|
|
249
|
+
## Author
|
|
250
|
+
|
|
251
|
+
Savant Realms
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration options for the Sentinel Analytics Realm plugin
|
|
3
|
+
*/
|
|
4
|
+
export interface SentinelAnalyticsRealmConfig {
|
|
5
|
+
projectId?: string;
|
|
6
|
+
appId?: string;
|
|
7
|
+
env?: string;
|
|
8
|
+
accessToken?: string;
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Event data structure for tracking
|
|
13
|
+
*/
|
|
14
|
+
export interface EventData {
|
|
15
|
+
name: string;
|
|
16
|
+
visitorId?: string;
|
|
17
|
+
userId?: string;
|
|
18
|
+
sessionId?: string;
|
|
19
|
+
category?: string;
|
|
20
|
+
action?: string;
|
|
21
|
+
label?: string;
|
|
22
|
+
value?: number;
|
|
23
|
+
properties?: Record<string, any>;
|
|
24
|
+
context?: Record<string, any>;
|
|
25
|
+
origin?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Response from the API
|
|
29
|
+
*/
|
|
30
|
+
export interface ApiResponse {
|
|
31
|
+
status?: string;
|
|
32
|
+
event_id?: string;
|
|
33
|
+
events?: Array<{
|
|
34
|
+
event_id: string;
|
|
35
|
+
status: string;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Client for plugging an app into the Sentinel Analytics Realm.
|
|
40
|
+
* Supports Option A (HTTP Ingestion) with the canonical event taxonomy.
|
|
41
|
+
*
|
|
42
|
+
* Works in both Node.js and browser environments.
|
|
43
|
+
*/
|
|
44
|
+
export declare class SentinelAnalyticsRealmPlugin {
|
|
45
|
+
private projectId?;
|
|
46
|
+
private appId?;
|
|
47
|
+
private env;
|
|
48
|
+
private accessToken?;
|
|
49
|
+
private baseUrl;
|
|
50
|
+
/**
|
|
51
|
+
* Creates a new instance of the Sentinel Analytics Realm plugin
|
|
52
|
+
*
|
|
53
|
+
* @param config Configuration options. Can also be read from environment variables:
|
|
54
|
+
* - SENTINEL_ANALYTICS_REALM_PROJECT_ID
|
|
55
|
+
* - SENTINEL_ANALYTICS_REALM_APP_ID
|
|
56
|
+
* - SENTINEL_ANALYTICS_REALM_ENV (defaults to 'prod')
|
|
57
|
+
* - SENTINEL_ANALYTICS_REALM_URL (defaults to 'https://api.sentinelanalyticsrealm.com')
|
|
58
|
+
*/
|
|
59
|
+
constructor(config?: SentinelAnalyticsRealmConfig);
|
|
60
|
+
/**
|
|
61
|
+
* Track a single event
|
|
62
|
+
*
|
|
63
|
+
* @param name Event name (required)
|
|
64
|
+
* @param eventData Additional event data
|
|
65
|
+
* @param timeout Request timeout in milliseconds (default: 5000)
|
|
66
|
+
* @returns API response or null on error
|
|
67
|
+
*/
|
|
68
|
+
track(name: string, eventData?: Omit<EventData, 'name'>, timeout?: number): Promise<ApiResponse | null>;
|
|
69
|
+
/**
|
|
70
|
+
* Track multiple events in one call
|
|
71
|
+
*
|
|
72
|
+
* @param events Array of event data objects, each must have a 'name' field
|
|
73
|
+
* @param timeout Request timeout in milliseconds (default: 10000)
|
|
74
|
+
* @returns API response or null on error
|
|
75
|
+
*/
|
|
76
|
+
trackBatch(events: EventData[], timeout?: number): Promise<ApiResponse | null>;
|
|
77
|
+
/**
|
|
78
|
+
* Convenience method for identity linking
|
|
79
|
+
*
|
|
80
|
+
* @param userId User ID (required)
|
|
81
|
+
* @param visitorId Visitor ID (optional)
|
|
82
|
+
* @param traits Additional user traits/properties
|
|
83
|
+
* @returns API response or null on error
|
|
84
|
+
*/
|
|
85
|
+
identify(userId: string, visitorId?: string, traits?: Record<string, any>): Promise<ApiResponse | null>;
|
|
86
|
+
/**
|
|
87
|
+
* Builds the event payload for the API
|
|
88
|
+
*/
|
|
89
|
+
private buildEventPayload;
|
|
90
|
+
/**
|
|
91
|
+
* Normalizes base URL by removing trailing slashes
|
|
92
|
+
*/
|
|
93
|
+
private normalizeBaseUrl;
|
|
94
|
+
/**
|
|
95
|
+
* Reads environment variable (Node.js only, returns undefined in browser)
|
|
96
|
+
*/
|
|
97
|
+
private readEnv;
|
|
98
|
+
}
|
|
99
|
+
export default SentinelAnalyticsRealmPlugin;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SentinelAnalyticsRealmPlugin = void 0;
|
|
4
|
+
const uuid_1 = require("uuid");
|
|
5
|
+
/**
|
|
6
|
+
* Client for plugging an app into the Sentinel Analytics Realm.
|
|
7
|
+
* Supports Option A (HTTP Ingestion) with the canonical event taxonomy.
|
|
8
|
+
*
|
|
9
|
+
* Works in both Node.js and browser environments.
|
|
10
|
+
*/
|
|
11
|
+
class SentinelAnalyticsRealmPlugin {
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new instance of the Sentinel Analytics Realm plugin
|
|
14
|
+
*
|
|
15
|
+
* @param config Configuration options. Can also be read from environment variables:
|
|
16
|
+
* - SENTINEL_ANALYTICS_REALM_PROJECT_ID
|
|
17
|
+
* - SENTINEL_ANALYTICS_REALM_APP_ID
|
|
18
|
+
* - SENTINEL_ANALYTICS_REALM_ENV (defaults to 'prod')
|
|
19
|
+
* - SENTINEL_ANALYTICS_REALM_URL (defaults to 'https://api.sentinelanalyticsrealm.com')
|
|
20
|
+
*/
|
|
21
|
+
constructor(config = {}) {
|
|
22
|
+
this.projectId = config.projectId || this.readEnv('SENTINEL_ANALYTICS_REALM_PROJECT_ID');
|
|
23
|
+
this.appId = config.appId || this.readEnv('SENTINEL_ANALYTICS_REALM_APP_ID');
|
|
24
|
+
this.env = config.env || this.readEnv('SENTINEL_ANALYTICS_REALM_ENV') || 'prod';
|
|
25
|
+
this.accessToken = config.accessToken;
|
|
26
|
+
this.baseUrl = this.normalizeBaseUrl(config.baseUrl ||
|
|
27
|
+
this.readEnv('SENTINEL_ANALYTICS_REALM_URL') ||
|
|
28
|
+
'https://api.sentinelanalyticsrealm.com');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Track a single event
|
|
32
|
+
*
|
|
33
|
+
* @param name Event name (required)
|
|
34
|
+
* @param eventData Additional event data
|
|
35
|
+
* @param timeout Request timeout in milliseconds (default: 5000)
|
|
36
|
+
* @returns API response or null on error
|
|
37
|
+
*/
|
|
38
|
+
async track(name, eventData = {}, timeout = 5000) {
|
|
39
|
+
const url = `${this.baseUrl}/api/v1/ingest/events`;
|
|
40
|
+
const headers = {
|
|
41
|
+
'Content-Type': 'application/json',
|
|
42
|
+
};
|
|
43
|
+
if (this.accessToken) {
|
|
44
|
+
headers['Authorization'] = `Bearer ${this.accessToken}`;
|
|
45
|
+
}
|
|
46
|
+
const payload = this.buildEventPayload({
|
|
47
|
+
name,
|
|
48
|
+
...eventData,
|
|
49
|
+
});
|
|
50
|
+
try {
|
|
51
|
+
const controller = new AbortController();
|
|
52
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
53
|
+
const response = await fetch(url, {
|
|
54
|
+
method: 'POST',
|
|
55
|
+
headers,
|
|
56
|
+
body: JSON.stringify(payload),
|
|
57
|
+
signal: controller.signal,
|
|
58
|
+
});
|
|
59
|
+
clearTimeout(timeoutId);
|
|
60
|
+
if (response.ok) {
|
|
61
|
+
const text = await response.text();
|
|
62
|
+
return text ? JSON.parse(text) : {};
|
|
63
|
+
}
|
|
64
|
+
// Swallow error; return null per Python SDK behavior
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
// Swallow error; return null per Python SDK behavior
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Track multiple events in one call
|
|
74
|
+
*
|
|
75
|
+
* @param events Array of event data objects, each must have a 'name' field
|
|
76
|
+
* @param timeout Request timeout in milliseconds (default: 10000)
|
|
77
|
+
* @returns API response or null on error
|
|
78
|
+
*/
|
|
79
|
+
async trackBatch(events, timeout = 10000) {
|
|
80
|
+
const url = `${this.baseUrl}/api/v1/ingest/events/batch`;
|
|
81
|
+
const headers = {
|
|
82
|
+
'Content-Type': 'application/json',
|
|
83
|
+
};
|
|
84
|
+
if (this.accessToken) {
|
|
85
|
+
headers['Authorization'] = `Bearer ${this.accessToken}`;
|
|
86
|
+
}
|
|
87
|
+
const batchPayload = {
|
|
88
|
+
project_id: this.projectId,
|
|
89
|
+
app_id: this.appId,
|
|
90
|
+
env: this.env,
|
|
91
|
+
events: events.map(event => this.buildEventPayload(event)),
|
|
92
|
+
};
|
|
93
|
+
try {
|
|
94
|
+
const controller = new AbortController();
|
|
95
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
96
|
+
const response = await fetch(url, {
|
|
97
|
+
method: 'POST',
|
|
98
|
+
headers,
|
|
99
|
+
body: JSON.stringify(batchPayload),
|
|
100
|
+
signal: controller.signal,
|
|
101
|
+
});
|
|
102
|
+
clearTimeout(timeoutId);
|
|
103
|
+
if (response.ok) {
|
|
104
|
+
const text = await response.text();
|
|
105
|
+
return text ? JSON.parse(text) : {};
|
|
106
|
+
}
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Convenience method for identity linking
|
|
115
|
+
*
|
|
116
|
+
* @param userId User ID (required)
|
|
117
|
+
* @param visitorId Visitor ID (optional)
|
|
118
|
+
* @param traits Additional user traits/properties
|
|
119
|
+
* @returns API response or null on error
|
|
120
|
+
*/
|
|
121
|
+
async identify(userId, visitorId, traits) {
|
|
122
|
+
return this.track('identify', {
|
|
123
|
+
userId,
|
|
124
|
+
visitorId,
|
|
125
|
+
properties: traits,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Builds the event payload for the API
|
|
130
|
+
*/
|
|
131
|
+
buildEventPayload(eventData) {
|
|
132
|
+
const now = new Date().toISOString();
|
|
133
|
+
const eventId = (0, uuid_1.v4)();
|
|
134
|
+
return {
|
|
135
|
+
project_id: this.projectId,
|
|
136
|
+
app_id: this.appId,
|
|
137
|
+
env: this.env,
|
|
138
|
+
event_id: eventId,
|
|
139
|
+
occurred_at: now,
|
|
140
|
+
sent_at: now,
|
|
141
|
+
origin: eventData.origin || 'real',
|
|
142
|
+
identity: {
|
|
143
|
+
visitor_id: eventData.visitorId || null,
|
|
144
|
+
user_id: eventData.userId || null,
|
|
145
|
+
session_id: eventData.sessionId || null,
|
|
146
|
+
},
|
|
147
|
+
event: {
|
|
148
|
+
name: eventData.name,
|
|
149
|
+
category: eventData.category || null,
|
|
150
|
+
action: eventData.action || null,
|
|
151
|
+
label: eventData.label || null,
|
|
152
|
+
value: eventData.value || null,
|
|
153
|
+
},
|
|
154
|
+
context: eventData.context || {},
|
|
155
|
+
properties: eventData.properties || {},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Normalizes base URL by removing trailing slashes
|
|
160
|
+
*/
|
|
161
|
+
normalizeBaseUrl(url) {
|
|
162
|
+
return url.endsWith('/') ? url.slice(0, -1) : url;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Reads environment variable (Node.js only, returns undefined in browser)
|
|
166
|
+
*/
|
|
167
|
+
readEnv(key) {
|
|
168
|
+
// In browser environment, process.env is not available
|
|
169
|
+
if (typeof process !== 'undefined' && process.env) {
|
|
170
|
+
return process.env[key];
|
|
171
|
+
}
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.SentinelAnalyticsRealmPlugin = SentinelAnalyticsRealmPlugin;
|
|
176
|
+
// Default export
|
|
177
|
+
exports.default = SentinelAnalyticsRealmPlugin;
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@savant-realms/sentinel-analytics-realm",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "TypeScript/JavaScript SDK for Sentinel Analytics Realm",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"test": "jest",
|
|
14
|
+
"lint": "eslint src --ext .ts",
|
|
15
|
+
"prepublishOnly": "npm run build"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"analytics",
|
|
19
|
+
"tracking",
|
|
20
|
+
"sentinel",
|
|
21
|
+
"savant-realms"
|
|
22
|
+
],
|
|
23
|
+
"author": "Savant Realms",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://gitlab.com/savant-realms/sentinel-analytics-realm-ts-js.git"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/jest": "^29.5.0",
|
|
34
|
+
"@types/node": "^20.0.0",
|
|
35
|
+
"@types/uuid": "^9.0.0",
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
37
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
38
|
+
"eslint": "^8.0.0",
|
|
39
|
+
"jest": "^29.5.0",
|
|
40
|
+
"ts-jest": "^29.1.0",
|
|
41
|
+
"typescript": "^5.0.0"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"uuid": "^9.0.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=14.0.0"
|
|
49
|
+
}
|
|
50
|
+
}
|