@cloudsignal/pwa-sdk 1.2.4 → 2.1.0
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/CHANGELOG.md +24 -22
- package/README.md +45 -509
- package/dist/{chunk-IMM7VF4N.js → chunk-IQHSODT4.js} +6 -6
- package/dist/chunk-IQHSODT4.js.map +1 -0
- package/dist/hmac-WITZIX2O.js +3 -0
- package/dist/{hmac-LWLR6F7Z.js.map → hmac-WITZIX2O.js.map} +1 -1
- package/dist/index.cjs +77 -86
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +31 -35
- package/dist/index.d.ts +31 -35
- package/dist/index.global.js +6 -6
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +76 -85
- package/dist/index.js.map +1 -1
- package/dist/service-worker.js +1 -1
- package/dist/service-worker.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-IMM7VF4N.js.map +0 -1
- package/dist/hmac-LWLR6F7Z.js +0 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isValidUUID } from './chunk-
|
|
2
|
-
export { generateAuthHeaders, generateHMACSignature, isValidUUID, makeAuthenticatedRequest } from './chunk-
|
|
1
|
+
import { isValidUUID } from './chunk-IQHSODT4.js';
|
|
2
|
+
export { generateAuthHeaders, generateHMACSignature, isValidUUID, makeAuthenticatedRequest } from './chunk-IQHSODT4.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* CloudSignal PWA SDK v1.0.0
|
|
@@ -934,13 +934,13 @@ function createAuthContext(config) {
|
|
|
934
934
|
onTokenExpired: config.onTokenExpired
|
|
935
935
|
};
|
|
936
936
|
}
|
|
937
|
-
if (!config.
|
|
938
|
-
throw new Error("Either userToken or
|
|
937
|
+
if (!config.organizationPublishableKey) {
|
|
938
|
+
throw new Error("Either userToken or organizationPublishableKey is required");
|
|
939
939
|
}
|
|
940
940
|
return {
|
|
941
941
|
mode: "hmac",
|
|
942
942
|
organizationId: config.organizationId,
|
|
943
|
-
|
|
943
|
+
organizationPublishableKey: config.organizationPublishableKey
|
|
944
944
|
};
|
|
945
945
|
}
|
|
946
946
|
async function makeAuthenticatedRequestWithContext(authContext, method, url, body, onTokenExpired) {
|
|
@@ -960,13 +960,13 @@ async function makeAuthenticatedRequestWithContext(authContext, method, url, bod
|
|
|
960
960
|
body
|
|
961
961
|
);
|
|
962
962
|
}
|
|
963
|
-
const { makeAuthenticatedRequest: makeAuthenticatedRequest4 } = await import('./hmac-
|
|
964
|
-
if (!authContext.
|
|
965
|
-
throw new Error("
|
|
963
|
+
const { makeAuthenticatedRequest: makeAuthenticatedRequest4 } = await import('./hmac-WITZIX2O.js');
|
|
964
|
+
if (!authContext.organizationPublishableKey) {
|
|
965
|
+
throw new Error("organizationPublishableKey required for HMAC auth mode");
|
|
966
966
|
}
|
|
967
967
|
return makeAuthenticatedRequest4(
|
|
968
968
|
authContext.organizationId,
|
|
969
|
-
authContext.
|
|
969
|
+
authContext.organizationPublishableKey,
|
|
970
970
|
method,
|
|
971
971
|
url,
|
|
972
972
|
body
|
|
@@ -1244,7 +1244,7 @@ var PushNotificationManager = class {
|
|
|
1244
1244
|
this.deviceDetector = new DeviceDetector();
|
|
1245
1245
|
this.authContext = createAuthContext({
|
|
1246
1246
|
organizationId: options.organizationId,
|
|
1247
|
-
|
|
1247
|
+
organizationPublishableKey: options.organizationPublishableKey,
|
|
1248
1248
|
userToken: options.userToken
|
|
1249
1249
|
});
|
|
1250
1250
|
this.onRegistered = options.onRegistered;
|
|
@@ -1370,6 +1370,64 @@ var PushNotificationManager = class {
|
|
|
1370
1370
|
return null;
|
|
1371
1371
|
}
|
|
1372
1372
|
}
|
|
1373
|
+
/**
|
|
1374
|
+
* Register a PWA installation without a push subscription.
|
|
1375
|
+
*
|
|
1376
|
+
* Tracks users who installed the PWA (standalone display mode) but
|
|
1377
|
+
* haven't granted notification permission yet. A subsequent
|
|
1378
|
+
* ``registerForPush()`` call upgrades the same row to a full push
|
|
1379
|
+
* registration (matched server-side by browser fingerprint).
|
|
1380
|
+
*
|
|
1381
|
+
* Guarded by a localStorage flag so repeat ``initialize()`` calls in
|
|
1382
|
+
* the same storage session are no-ops.
|
|
1383
|
+
*/
|
|
1384
|
+
async registerInstallation() {
|
|
1385
|
+
try {
|
|
1386
|
+
if (isInstallationRegistered(this.organizationId, this.serviceId)) {
|
|
1387
|
+
this.log("Installation already registered, skipping");
|
|
1388
|
+
return null;
|
|
1389
|
+
}
|
|
1390
|
+
const fingerprint = await generateBrowserFingerprint();
|
|
1391
|
+
const deviceInfo = this.deviceDetector.getDeviceInfo();
|
|
1392
|
+
const platformInfo = this.deviceDetector.getPlatformInfo();
|
|
1393
|
+
const installationData = {
|
|
1394
|
+
service_id: this.serviceId,
|
|
1395
|
+
browser_fingerprint: fingerprint || void 0,
|
|
1396
|
+
device_type: deviceInfo.deviceType,
|
|
1397
|
+
device_model: deviceInfo.deviceModel,
|
|
1398
|
+
browser_name: platformInfo.browser,
|
|
1399
|
+
browser_version: platformInfo.browserVersion,
|
|
1400
|
+
os_name: platformInfo.os,
|
|
1401
|
+
os_version: platformInfo.osVersion,
|
|
1402
|
+
user_agent: platformInfo.userAgent,
|
|
1403
|
+
display_mode: "standalone",
|
|
1404
|
+
is_installed: true,
|
|
1405
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
1406
|
+
language: navigator.language || "en-US"
|
|
1407
|
+
};
|
|
1408
|
+
const url = `${this.serviceUrl}/api/v1/registration/install-only`;
|
|
1409
|
+
const response = await makeAuthenticatedRequestWithContext(
|
|
1410
|
+
this.authContext,
|
|
1411
|
+
"POST",
|
|
1412
|
+
url,
|
|
1413
|
+
installationData,
|
|
1414
|
+
this.onTokenExpired
|
|
1415
|
+
);
|
|
1416
|
+
if (!response.ok) {
|
|
1417
|
+
const errorText = await response.text();
|
|
1418
|
+
throw new Error(`Installation registration failed: ${response.status} - ${errorText}`);
|
|
1419
|
+
}
|
|
1420
|
+
const result = await response.json();
|
|
1421
|
+
markInstallationRegistered(this.organizationId, this.serviceId, result.registration_id);
|
|
1422
|
+
this.log(`Installation registered: ${result.registration_id}`);
|
|
1423
|
+
return { registrationId: result.registration_id };
|
|
1424
|
+
} catch (error) {
|
|
1425
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
1426
|
+
this.log(`Installation registration failed: ${err.message}`, "error");
|
|
1427
|
+
this.onError?.(err);
|
|
1428
|
+
return null;
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1373
1431
|
/**
|
|
1374
1432
|
* Unregister from push notifications
|
|
1375
1433
|
*/
|
|
@@ -1483,72 +1541,6 @@ var PushNotificationManager = class {
|
|
|
1483
1541
|
return null;
|
|
1484
1542
|
}
|
|
1485
1543
|
}
|
|
1486
|
-
/**
|
|
1487
|
-
* Register PWA installation without push subscription.
|
|
1488
|
-
* This tracks users who installed the PWA but haven't subscribed to notifications.
|
|
1489
|
-
* Called automatically when installation is detected.
|
|
1490
|
-
*
|
|
1491
|
-
* @returns Installation registration result or null if already registered/failed
|
|
1492
|
-
*/
|
|
1493
|
-
async registerInstallation() {
|
|
1494
|
-
try {
|
|
1495
|
-
if (isInstallationRegistered(this.organizationId, this.serviceId)) {
|
|
1496
|
-
this.log("Installation already registered, skipping");
|
|
1497
|
-
return null;
|
|
1498
|
-
}
|
|
1499
|
-
const fingerprint = await generateBrowserFingerprint();
|
|
1500
|
-
const deviceInfo = this.deviceDetector.getDeviceInfo();
|
|
1501
|
-
const platformInfo = this.deviceDetector.getPlatformInfo();
|
|
1502
|
-
const installationData = {
|
|
1503
|
-
service_id: this.serviceId,
|
|
1504
|
-
browser_fingerprint: fingerprint || void 0,
|
|
1505
|
-
device_type: deviceInfo.deviceType,
|
|
1506
|
-
device_model: deviceInfo.deviceModel,
|
|
1507
|
-
browser_name: platformInfo.browser,
|
|
1508
|
-
browser_version: platformInfo.browserVersion,
|
|
1509
|
-
os_name: platformInfo.os,
|
|
1510
|
-
os_version: platformInfo.osVersion,
|
|
1511
|
-
user_agent: platformInfo.userAgent,
|
|
1512
|
-
display_mode: "standalone",
|
|
1513
|
-
is_installed: true,
|
|
1514
|
-
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
1515
|
-
language: navigator.language || "en-US"
|
|
1516
|
-
};
|
|
1517
|
-
const url = `${this.serviceUrl}/api/v1/registration/install-only`;
|
|
1518
|
-
const response = await makeAuthenticatedRequestWithContext(
|
|
1519
|
-
this.authContext,
|
|
1520
|
-
"POST",
|
|
1521
|
-
url,
|
|
1522
|
-
installationData,
|
|
1523
|
-
this.onTokenExpired
|
|
1524
|
-
);
|
|
1525
|
-
if (!response.ok) {
|
|
1526
|
-
const errorText = await response.text();
|
|
1527
|
-
throw new Error(`Installation registration failed: ${response.status} - ${errorText}`);
|
|
1528
|
-
}
|
|
1529
|
-
const result = await response.json();
|
|
1530
|
-
markInstallationRegistered(this.organizationId, this.serviceId, result.registration_id);
|
|
1531
|
-
this.log(`Installation registered successfully: ${result.registration_id}`);
|
|
1532
|
-
return { registrationId: result.registration_id };
|
|
1533
|
-
} catch (error) {
|
|
1534
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
1535
|
-
this.log(`Installation registration failed: ${err.message}`, "error");
|
|
1536
|
-
this.onError?.(err);
|
|
1537
|
-
return null;
|
|
1538
|
-
}
|
|
1539
|
-
}
|
|
1540
|
-
/**
|
|
1541
|
-
* Check if installation is already registered
|
|
1542
|
-
*/
|
|
1543
|
-
isInstallationRegistered() {
|
|
1544
|
-
return isInstallationRegistered(this.organizationId, this.serviceId);
|
|
1545
|
-
}
|
|
1546
|
-
/**
|
|
1547
|
-
* Get stored installation registration ID
|
|
1548
|
-
*/
|
|
1549
|
-
getInstallationId() {
|
|
1550
|
-
return getStorageItem(`install_id_${this.organizationId}_${this.serviceId}`);
|
|
1551
|
-
}
|
|
1552
1544
|
/**
|
|
1553
1545
|
* Request notification permission
|
|
1554
1546
|
*/
|
|
@@ -1642,7 +1634,7 @@ var HeartbeatManager = class {
|
|
|
1642
1634
|
this.onTokenExpired = options.onTokenExpired;
|
|
1643
1635
|
this.authContext = createAuthContext({
|
|
1644
1636
|
organizationId: options.organizationId,
|
|
1645
|
-
|
|
1637
|
+
organizationPublishableKey: options.organizationPublishableKey,
|
|
1646
1638
|
userToken: options.userToken
|
|
1647
1639
|
});
|
|
1648
1640
|
this.config = {
|
|
@@ -3079,7 +3071,7 @@ var IOSInstallBanner = class {
|
|
|
3079
3071
|
|
|
3080
3072
|
// src/CloudSignalPWA.ts
|
|
3081
3073
|
var DEFAULT_SERVICE_URL = "https://pwa.cloudsignal.app";
|
|
3082
|
-
var SDK_VERSION = "1.2.
|
|
3074
|
+
var SDK_VERSION = "1.2.0";
|
|
3083
3075
|
var CloudSignalPWA = class {
|
|
3084
3076
|
constructor(config) {
|
|
3085
3077
|
this.initialized = false;
|
|
@@ -3093,12 +3085,12 @@ var CloudSignalPWA = class {
|
|
|
3093
3085
|
this.config = config;
|
|
3094
3086
|
this.serviceUrl = config.serviceUrl || DEFAULT_SERVICE_URL;
|
|
3095
3087
|
this.debug = config.debug ?? false;
|
|
3096
|
-
if (!config.
|
|
3097
|
-
throw new Error("Either
|
|
3088
|
+
if (!config.organizationPublishableKey && !config.userToken) {
|
|
3089
|
+
throw new Error("Either organizationPublishableKey or userToken must be provided");
|
|
3098
3090
|
}
|
|
3099
3091
|
this.authContext = createAuthContext({
|
|
3100
3092
|
organizationId: config.organizationId,
|
|
3101
|
-
|
|
3093
|
+
organizationPublishableKey: config.organizationPublishableKey,
|
|
3102
3094
|
userToken: config.userToken
|
|
3103
3095
|
});
|
|
3104
3096
|
this.deviceDetector = new DeviceDetector();
|
|
@@ -3119,7 +3111,7 @@ var CloudSignalPWA = class {
|
|
|
3119
3111
|
this.pushNotificationManager = new PushNotificationManager({
|
|
3120
3112
|
serviceUrl: this.serviceUrl,
|
|
3121
3113
|
organizationId: config.organizationId,
|
|
3122
|
-
|
|
3114
|
+
organizationPublishableKey: config.organizationPublishableKey,
|
|
3123
3115
|
userToken: config.userToken,
|
|
3124
3116
|
onTokenExpired: config.onTokenExpired,
|
|
3125
3117
|
serviceId: config.serviceId,
|
|
@@ -3138,7 +3130,7 @@ var CloudSignalPWA = class {
|
|
|
3138
3130
|
this.heartbeatManager = new HeartbeatManager({
|
|
3139
3131
|
serviceUrl: this.serviceUrl,
|
|
3140
3132
|
organizationId: config.organizationId,
|
|
3141
|
-
|
|
3133
|
+
organizationPublishableKey: config.organizationPublishableKey,
|
|
3142
3134
|
userToken: config.userToken,
|
|
3143
3135
|
onTokenExpired: config.onTokenExpired,
|
|
3144
3136
|
config: config.heartbeat,
|
|
@@ -3227,10 +3219,9 @@ var CloudSignalPWA = class {
|
|
|
3227
3219
|
}
|
|
3228
3220
|
const installState = this.installationManager.getState();
|
|
3229
3221
|
if (installState.isInstalled) {
|
|
3230
|
-
this.log("PWA installation detected, registering
|
|
3222
|
+
this.log("PWA installation detected, registering\u2026");
|
|
3231
3223
|
const installResult = await this.pushNotificationManager.registerInstallation();
|
|
3232
3224
|
if (installResult) {
|
|
3233
|
-
this.log(`Installation registered: ${installResult.registrationId}`);
|
|
3234
3225
|
this.emit("install:registered", { registrationId: installResult.registrationId });
|
|
3235
3226
|
}
|
|
3236
3227
|
}
|