@novacraft-engineering/pulsar-code-push 1.5.4 → 1.6.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@novacraft-engineering/pulsar-code-push",
3
- "version": "1.5.4",
4
- "description": "Pulsar OTA client for React Native — over-the-air JavaScript updates. A CodePush-compatible client (RevoPush lineage) pointed at Pulsar.",
3
+ "version": "1.6.0",
4
+ "description": "Pulsar OTA client for React Native \u2014 over-the-air JavaScript updates. A CodePush-compatible client (RevoPush lineage) pointed at Pulsar.",
5
5
  "main": "CodePush.js",
6
6
  "typings": "typings/react-native-code-push.d.ts",
7
7
  "homepage": "https://pulsar.novacraft.africa",
@@ -1,6 +1,17 @@
1
+ const { Platform } = require("react-native");
1
2
  const packageJson = require("./package.json");
2
3
  const { getTargetingInfo } = require("./targeting");
3
4
 
5
+ // React Native's default agent carries no usable platform detail — iOS sends a Darwin/CFNetwork
6
+ // string with no "iPhone OS x_y", and Android goes out through OkHttp as bare "okhttp/4.x". Both
7
+ // left the server guessing (Android was filed as "unknown" entirely, OS version was always empty),
8
+ // so state it explicitly instead.
9
+ function userAgent() {
10
+ const os = Platform.OS === "ios" ? "iOS" : Platform.OS === "android" ? "Android" : Platform.OS;
11
+ const version = Platform.Version === undefined || Platform.Version === null ? "" : String(Platform.Version);
12
+ return `Pulsar/${packageJson.version} (${os}${version ? " " + version : ""})`;
13
+ }
14
+
4
15
  module.exports = {
5
16
  async request(verb, url, requestBody, callback) {
6
17
  if (typeof requestBody === "function") {
@@ -9,18 +20,32 @@ module.exports = {
9
20
  }
10
21
 
11
22
  // Scope the update-check to a specific device model / user id when the host app has set them.
12
- // Only the GET update_check request is augmented; report_status is untouched.
23
+ const { userId, deviceModel } = getTargetingInfo();
13
24
  if (verb === 0 && url.indexOf("update_check") !== -1) {
14
- const { userId, deviceModel } = getTargetingInfo();
15
25
  const extra = [];
16
26
  if (deviceModel) extra.push("device_model=" + encodeURIComponent(deviceModel));
17
27
  if (userId) extra.push("user_id=" + encodeURIComponent(userId));
18
28
  if (extra.length) url += (url.indexOf("?") === -1 ? "?" : "&") + extra.join("&");
19
29
  }
20
30
 
31
+ // Status reports carry the same identity. update_check only records a device when an update is
32
+ // actually served, so without this the device/user targeting lists never fill on a quiet app.
33
+ // The acquisition SDK hands us an already-stringified body here, so parse before augmenting.
34
+ if (url.indexOf("report_status") !== -1 && requestBody && (deviceModel || userId)) {
35
+ try {
36
+ const parsed = typeof requestBody === "string" ? JSON.parse(requestBody) : requestBody;
37
+ if (deviceModel && !parsed.device_model) parsed.device_model = deviceModel;
38
+ if (userId && !parsed.user_id) parsed.user_id = userId;
39
+ requestBody = parsed;
40
+ } catch (err) {
41
+ // A body we can't parse is left exactly as-is — reporting must never fail over telemetry.
42
+ }
43
+ }
44
+
21
45
  const headers = {
22
46
  "Accept": "application/json",
23
47
  "Content-Type": "application/json",
48
+ "User-Agent": userAgent(),
24
49
  "X-CodePush-Plugin-Name": packageJson.name,
25
50
  "X-CodePush-Plugin-Version": packageJson.version,
26
51
  "X-CodePush-SDK-Version": packageJson.dependencies["code-push"]