@mostly-good-metrics/javascript 0.2.0 → 0.4.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/dist/cjs/client.js +74 -2
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/network.js +7 -0
- package/dist/cjs/network.js.map +1 -1
- package/dist/cjs/storage.js +61 -0
- package/dist/cjs/storage.js.map +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils.js +22 -0
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/client.js +75 -3
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/network.js +7 -0
- package/dist/esm/network.js.map +1 -1
- package/dist/esm/storage.js +61 -0
- package/dist/esm/storage.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils.js +20 -0
- package/dist/esm/utils.js.map +1 -1
- package/dist/types/client.d.ts +40 -0
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/network.d.ts.map +1 -1
- package/dist/types/storage.d.ts +23 -1
- package/dist/types/storage.d.ts.map +1 -1
- package/dist/types/types.d.ts +24 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils.d.ts +8 -0
- package/dist/types/utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/client.test.ts +143 -0
- package/src/client.ts +86 -2
- package/src/network.test.ts +244 -0
- package/src/network.ts +7 -0
- package/src/storage.test.ts +150 -1
- package/src/storage.ts +66 -1
- package/src/types.ts +29 -0
- package/src/utils.test.ts +31 -0
- package/src/utils.ts +21 -0
package/src/types.ts
CHANGED
|
@@ -134,6 +134,11 @@ export interface MGMEvent {
|
|
|
134
134
|
*/
|
|
135
135
|
name: string;
|
|
136
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Unique client-generated ID for deduplication.
|
|
139
|
+
*/
|
|
140
|
+
client_event_id: string;
|
|
141
|
+
|
|
137
142
|
/**
|
|
138
143
|
* ISO8601 timestamp when the event occurred.
|
|
139
144
|
*/
|
|
@@ -159,6 +164,11 @@ export interface MGMEvent {
|
|
|
159
164
|
*/
|
|
160
165
|
appVersion?: string;
|
|
161
166
|
|
|
167
|
+
/**
|
|
168
|
+
* The app build number (separate from version).
|
|
169
|
+
*/
|
|
170
|
+
appBuildNumber?: string;
|
|
171
|
+
|
|
162
172
|
/**
|
|
163
173
|
* The OS version string.
|
|
164
174
|
*/
|
|
@@ -169,6 +179,21 @@ export interface MGMEvent {
|
|
|
169
179
|
*/
|
|
170
180
|
environment: string;
|
|
171
181
|
|
|
182
|
+
/**
|
|
183
|
+
* The device manufacturer (e.g., "Apple", "Samsung").
|
|
184
|
+
*/
|
|
185
|
+
deviceManufacturer?: string;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The user's locale (e.g., "en-US").
|
|
189
|
+
*/
|
|
190
|
+
locale?: string;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* The user's timezone (e.g., "America/New_York").
|
|
194
|
+
*/
|
|
195
|
+
timezone?: string;
|
|
196
|
+
|
|
172
197
|
/**
|
|
173
198
|
* Custom properties attached to this event.
|
|
174
199
|
*/
|
|
@@ -182,10 +207,14 @@ export interface MGMEvent {
|
|
|
182
207
|
export interface MGMEventContext {
|
|
183
208
|
platform: Platform;
|
|
184
209
|
appVersion?: string;
|
|
210
|
+
appBuildNumber?: string;
|
|
185
211
|
osVersion?: string;
|
|
186
212
|
userId?: string;
|
|
187
213
|
sessionId?: string;
|
|
188
214
|
environment: string;
|
|
215
|
+
deviceManufacturer?: string;
|
|
216
|
+
locale?: string;
|
|
217
|
+
timezone?: string;
|
|
189
218
|
}
|
|
190
219
|
|
|
191
220
|
/**
|
package/src/utils.test.ts
CHANGED
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
validateEventName,
|
|
6
6
|
sanitizeProperties,
|
|
7
7
|
resolveConfiguration,
|
|
8
|
+
getLocale,
|
|
9
|
+
getTimezone,
|
|
8
10
|
} from './utils';
|
|
9
11
|
import { Constraints, DefaultConfiguration, MGMError } from './types';
|
|
10
12
|
|
|
@@ -237,3 +239,32 @@ describe('resolveConfiguration', () => {
|
|
|
237
239
|
expect(config.maxStoredEvents).toBe(Constraints.MIN_STORED_EVENTS);
|
|
238
240
|
});
|
|
239
241
|
});
|
|
242
|
+
|
|
243
|
+
describe('getLocale', () => {
|
|
244
|
+
it('should return a non-empty string', () => {
|
|
245
|
+
const locale = getLocale();
|
|
246
|
+
expect(typeof locale).toBe('string');
|
|
247
|
+
expect(locale.length).toBeGreaterThan(0);
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it('should return a locale-like string (e.g., en, en-US)', () => {
|
|
251
|
+
const locale = getLocale();
|
|
252
|
+
// Locale should be something like "en", "en-US", "fr-FR", etc.
|
|
253
|
+
expect(locale).toMatch(/^[a-z]{2}(-[A-Z]{2})?$/i);
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
describe('getTimezone', () => {
|
|
258
|
+
it('should return a string', () => {
|
|
259
|
+
const timezone = getTimezone();
|
|
260
|
+
expect(typeof timezone).toBe('string');
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('should return a valid IANA timezone or empty string', () => {
|
|
264
|
+
const timezone = getTimezone();
|
|
265
|
+
// Should be empty or a valid IANA timezone like "America/New_York" or "UTC"
|
|
266
|
+
if (timezone) {
|
|
267
|
+
expect(timezone).toMatch(/^([A-Za-z_]+\/[A-Za-z_]+|UTC)$/);
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
});
|
package/src/utils.ts
CHANGED
|
@@ -310,3 +310,24 @@ export function getDeviceModel(): string {
|
|
|
310
310
|
export function delay(ms: number): Promise<void> {
|
|
311
311
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
312
312
|
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Get the user's locale.
|
|
316
|
+
*/
|
|
317
|
+
export function getLocale(): string {
|
|
318
|
+
if (typeof navigator !== 'undefined') {
|
|
319
|
+
return navigator.language || 'en';
|
|
320
|
+
}
|
|
321
|
+
return 'en';
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Get the user's timezone.
|
|
326
|
+
*/
|
|
327
|
+
export function getTimezone(): string {
|
|
328
|
+
try {
|
|
329
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone || '';
|
|
330
|
+
} catch {
|
|
331
|
+
return '';
|
|
332
|
+
}
|
|
333
|
+
}
|