Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
node_modules/
node_modules/
coverage/
android/build/
ios/Pods/
example/AwesomeProject/
example/ExpoProject/
23 changes: 22 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,29 @@
"sourceType": "module",
"project": ["**/tsconfig.json"]
},
"globals": {
"ErrorUtils": "readonly"
},
"overrides": [
{
"files": ["__tests__/**/*"],
"env": {
"jest": true
},
"rules": {
"quotes": ["error", "single", { "avoidEscape": true }],
"global-require": "off",
"no-await-in-loop": "off",
"no-promise-executor-return": "off"
}
},
{
"files": ["scripts/**/*"],
"env": {
"node": true
},
"rules": {
"no-template-curly-in-string": "off"
}
}
],
Expand All @@ -38,6 +56,8 @@
"no-var": "off",
"func-names": "off",
"consistent-return": "off",
"no-continue": "off",
"class-methods-use-this": "off",
"prefer-rest-params": "off",
"radix": "off",
"prefer-spread": "off",
Expand Down Expand Up @@ -175,7 +195,8 @@
"no-useless-concat": "off",
"quotes": [
"error",
"double"
"double",
{ "avoidEscape": true }
],
"no-console": [
"off"
Expand Down
5 changes: 5 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ updates:
open-pull-requests-limit: 10
target-branch: staging
versioning-strategy: increase-if-necessary
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: monthly
target-branch: staging
36 changes: 36 additions & 0 deletions .github/workflows/js_checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: JS checks
on:
pull_request:
push:
branches: [master, staging, master-np, staging-np]
workflow_dispatch:
permissions:
contents: read
jobs:
checks:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [22, 24]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
- run: npm ci --ignore-scripts
- name: Lint
run: npx eslint .
- name: Type check Countly.d.ts
run: npx tsc -p tsconfig.types.json
- name: Unit tests
run: npx jest
- name: Generate and test the no-push package
if: hashFiles('scripts/generate-no-push.js') != ''
run: |
node scripts/generate-no-push.js "$RUNNER_TEMP/no-push"
cd "$RUNNER_TEMP/no-push"
npm ci --ignore-scripts
npx tsc -p tsconfig.types.json
npx jest
8 changes: 5 additions & 3 deletions .github/workflows/release_notice.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ on:
release:
types: [published]
workflow_dispatch:
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
Expand All @@ -14,7 +16,7 @@ jobs:
run: echo "$GITHUB_CONTEXT"
- name: Send custom JSON data to Slack workflow
id: slack
uses: slackapi/slack-github-action@v1.23.0
uses: slackapi/slack-github-action@007b2c3c751a190b6f0f040e47ed024deaa72844 # v1.23.0
with:
# This data can be any valid JSON from a previous step in the GitHub Action
payload: |
Expand All @@ -28,12 +30,12 @@ jobs:
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_RELEASE }}
- name: Send custom JSON data to Discord
uses: sarisia/actions-status-discord@v1.13.0
uses: sarisia/actions-status-discord@9904e3130b8905d5b973df25623f17672dcb3466 # v1.13.0
with:
webhook: ${{ secrets.DISCORD_WEBHOOK_URL }}
nodetail: true
title: New ${{ github.repository }} version ${{ github.event.release.tag_name }} published by ${{ github.actor }}
description: |
Release URL: ${{ github.event.release.html_url }}
Click [here](https://github.com/Countly/countly-server/blob/master/CHANGELOG.md) to view the change log.
Click [here](${{ github.server_url }}/${{ github.repository }}/blob/${{ github.event.release.tag_name }}/CHANGELOG.md) to view the change log.
`${{ github.event.release.body }}`
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ android/.classpath
countly-sdk-react-native-bridge-*.tgz
example/AwesomeProject
coverage/
package-lock.json
example/AwesomeProject/*
example/ExpoProject/*
example/ExpoProject/*
hs_err_pid*.log
replay_pid*.log
12 changes: 10 additions & 2 deletions .prettierrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@
"jsxBracketSameLine": false,
"jsxSingleQuote": false,
"quoteProps": "preserve",
"singleQuote": true,
"singleQuote": false,
"semi": true,
"printWidth": 300,
"useTabs": false,
"tabWidth": 4,
"trailingComma": "es5",
"endOfLine": "lf"
"endOfLine": "lf",
"overrides": [
{
"files": "__tests__/**",
"options": {
"singleQuote": true
}
}
]
}
64 changes: 0 additions & 64 deletions .travis.yml

This file was deleted.

76 changes: 74 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,73 @@
## XX.XX.XX-np
* ! Minor breaking change ! `Countly.remoteConfig.updateForKeysOnly` and `updateExceptKeys` now enroll the user only in the A/B tests of the downloaded keys in iOS, not in all running A/B tests.
* ! Minor breaking change ! `Countly.remoteConfig.getValue` now returns string values as strings in Android. Before, "2.10" came back as 2.1.
* ! Minor breaking change ! `Countly.logException(exception, false)` now records a fatal crash.
* ! Minor breaking change ! An uncaught JS error that crashes a release build is now recorded once, as a fatal crash with its JS stack, instead of twice.
* ! Minor breaking change ! The Firebase BoM is updated from 28.4.2 to 32.8.1 (firebase-messaging 23.4.1) in Android. Apps that use an older Firebase BoM get the versions of 32.8.1 for their Firebase libraries, and the Kotlin standard library 1.7.10 joins the build. The minimum Android version stays API 21.
* ! Minor breaking change ! `Countly.test` helpers now work only in debug builds.
* ! Minor breaking change ! The package now ships only the files the SDK needs at runtime; the example app, the tests and the Xcode project for manual linking are no longer part of it. It declares `react-native` as a peer dependency and needs React Native 0.62 or newer.
* ! Minor breaking change ! The pod now makes only the bridge header and the iOS SDK's public headers public; other headers can no longer be imported from it. The `NotificationService` subspec no longer depends on React, and `pod 'CountlyReactNative'` installs only the `Core` subspec. With React Native 0.71 and newer, the pod's iOS deployment target now follows React Native's minimum iOS version.

* Added a `{ success, error }` result to `Countly.remoteConfig.update`, `updateForKeysOnly` and `updateExceptKeys`.
* Added `Countly.registerForNotificationOpened(listener)`. It is called when the user taps a push, in Android and iOS, with the push data and the tapped action index: 0 for the notification, 1 and up for its buttons. A tap that started the app is delivered once a listener is registered. In Android, call `setIntent(intent)` in your MainActivity's `onNewIntent` so a tap that brings back a stopped app is delivered too.
* Added support for objects as campaign data in `recordDirectAttribution` and as values in `recordIndirectAttribution`, in `Countly` and in `CountlyConfig`.
* Added the names "DEVELOPMENT", "PRODUCTION" and "ADHOC" as accepted values of `CountlyConfig.setPushTokenType`.

* Mitigated remote config update issues:
* Updates without remote config consent, in temporary device ID mode or with SDK networking disabled now complete with an error in iOS, instead of never completing.
* Failed updates are now logged as errors in iOS.
* An update without remote config consent is now reported as failed in Android.
* Mitigated crash reporting issues:
* The JS crash handler no longer fails, or skips the app's previous error handler, when the app throws a value that is not an Error.
* `Countly.logException` now skips `null` and `undefined` segment values instead of failing.
* Mitigated an issue where `CountlyConfig.setLocation` was ignored without a country code in iOS.
* Mitigated an issue where `Countly.giveAllConsent` sent two consent requests in iOS.
* Mitigated start-up issues:
* An empty or `null` device ID at init no longer becomes the device ID "null" in Android; the SDK generates one instead, and installs that already have "null" get a new ID on their next start.
* A partly set push config, a single consent name instead of a list, or attribution data of the wrong type no longer skips the rest of the init config in Android, or crashes the app.
* `Countly.initWithConfig` now refuses a missing server URL or app key with an error log, and its promise settles when the native init fails.
* A logging choice made with `Countly.setLoggingEnabled` before init is now kept in iOS.
* Mitigated push notification issues:
* A token handed over with `Countly.sendPushToken` is now registered without calling `Countly.askForNotificationPermission` first in Android, and a token renewed by Firebase while the SDK runs is sent.
* `Countly.sendPushToken` now sends the token in iOS, with the token type set by `CountlyConfig.setPushTokenType`, also when Countly push notifications are disabled.
* A push tapped while the app starts is now counted once in iOS.
* The push payload is now logged only when logging is enabled in iOS.
* `Countly.askForNotificationPermission` now shows the notification permission prompt on Android 13 and newer; the bridge declares `POST_NOTIFICATIONS` for it.
* A push tap that starts the app now gets the intent redirection check in Android, as warm taps already did.
* The push token is no longer sent before the user allows notifications in iOS.
* Registering `Countly.registerForNotification` again now replaces the earlier listener, so each push reaches JS once.
* `Countly.sendPushToken` now returns an error message when it is called before init.
* Mitigated data issues:
* Event sums keep their full precision in iOS.
* Whole numbers in user properties are now sent without exponent notation in Android, for example 5551234567 instead of 5.551234567E9.
* `null` values and numbers in data the bridge returns to JS now arrive as `null` and numbers in Android.
* The "metrics" consent can now be given and removed after init in Android.
* `incrementBy`, `multiply`, `saveMax` and `saveMin` in `Countly.userData` and `Countly.userDataBulk` no longer send a changed value for decimals or numbers outside the 32-bit integer range; they refuse them with an error message.
* Mitigated crash and input issues:
* `Countly.logException` now accepts Error objects.
* JS crash titles now name the function and the bundle file the error came from, by file name only, without device or build paths.
* `Countly.recordMetrics` before init, a survey reported as closed with a `null` result, and inputs of the wrong type no longer crash the app or leave a promise unsettled.
* `Countly.setCustomCrashSegments` after init, where it has no effect, now returns a warning. Set crash segments before `Countly.initWithConfig`.
* Mitigated an issue where `Countly.feedback.presentFeedbackWidget` ignored the close button text in Android.
* Mitigated an issue where the content callback status was a number in iOS; it is now the text "COMPLETED" or "CLOSED", the same as in Android.
* Mitigated an issue where the iOS privacy manifest was not bundled with the pod.
* Mitigated an issue where the Android build file set app-only values and its own build script when used inside an app.
* Mitigated TypeScript declaration issues: `Countly.d.ts` now compiles in strict mode, and its types match the API.

* No-push package (`countly-sdk-react-native-bridge-np`) specific changes:
* The package is now generated from the same source as the push package, so it gets every change at the same time.
* Android now reports the SDK name `js-rnbnp-android`, which the server recognizes, instead of `js-rnb-android-np`.
* iOS no longer compiles push notification code.
* Push notification calls and push config options are ignored with a warning log.

* Removed these deprecated functions. The remote config replacements return a promise, and `getValue` returns `null` for a missing key:
* `Countly.recordView`, use `Countly.views.startAutoStoppedView`
* `Countly.remoteConfigUpdate`, use `Countly.remoteConfig.update`
* `Countly.updateRemoteConfigForKeysOnly`, use `Countly.remoteConfig.updateForKeysOnly`
* `Countly.updateRemoteConfigExceptKeys`, use `Countly.remoteConfig.updateExceptKeys`
* `Countly.getRemoteConfigValueForKey` and `Countly.getRemoteConfigValueForKeyP`, use `Countly.remoteConfig.getValue`
* `Countly.remoteConfigClearValues`, use `Countly.remoteConfig.clearValues`

## 26.1.0-np
* Added a new `Countly.sessions` interface for manual session control:
* `beginSession()`
Expand Down Expand Up @@ -41,7 +111,7 @@
* Added `Countly.remoteConfig.getValue(keyName)` as the async replacement for the older root-level remote config getters. It returns `null` when a value is missing.
* Added `Countly.addCustomNetworkRequestHeaders(...)` for runtime request header updates.
* Added `Countly.content.previewContent(contentId)` for direct content previews.
* Added `Countly.webViewDisplayOption` constants and `.content.setWebViewDisplayOption(...)` for controlling content and feedback presentation.
* Added `Countly.webViewDisplayOption` constants and `CountlyConfig.content.setWebViewDisplayOption(...)` for controlling content and feedback presentation.
* Added direct `Countly.feedback.presentNPS(...)`, `Countly.feedback.presentSurvey(...)`, and `Countly.feedback.presentRating(...)` helpers backed by the latest native feedback APIs.
* Added `Countly.deviceId.changeID(newDeviceID, merge)` to the device ID interface for explicit merge control after removing the old root-level `Countly.changeDeviceId(...)` API.
* Added init config options for manual session control, hybrid manual session mode, automatic view tracking, global view segmentation, custom network request headers, and disabling auto view restart.
Expand All @@ -56,6 +126,7 @@
* Mitigated an issue where `Countly.initWithConfig(...)` could preserve an empty `deviceID` under the wrong field name instead of clearing the init payload value.
* Mitigated an issue where `allowedIntentPackageNames` could be dropped from init config serialization unless `allowedIntentClassNames` was also provided.
* Mitigated an inconsistency where `Countly.deviceId.setID(Countly.TemporaryDeviceIDString)` did not route temporary-device-ID mode through the dedicated native handling on Android, and now does so explicitly on both Android and iOS.
* ! Major breaking change ! Removed these deprecated functions. Apps that still call them must move to the replacement named on each line:
* Removed `Countly.init(...)`. Use `Countly.initWithConfig(countlyConfig)`.
* Removed `Countly.hasBeenCalledOnStart()`. No direct replacement.
* Removed `Countly.sendEvent(...)`. Use `Countly.events.recordEvent(...)`.
Expand All @@ -78,6 +149,7 @@
* Removed `Countly.enableApm()` and `CountlyConfig.enableApm()`. Use the `CountlyConfig.apm` interface, including `enableAppStartTimeTracking()`, `enableForegroundBackgroundTracking()`, and `enableManualAppLoadedTrigger()` as needed.
* Removed `Countly.enableAttribution(...)` and `Countly.recordAttributionID(...)`. Use `Countly.recordIndirectAttribution(...)`.
* Removed `CountlyConfig.pushTokenType(...)`. Use `CountlyConfig.setPushTokenType(...)` and `CountlyConfig.setPushNotificationChannelInformation(...)`.
* With `CountlyConfig.enableCrashReporting()`, `Countly.initWithConfig` now installs the JS crash handler. It reports uncaught JS errors, then calls the error handler the app had before.

* Android specific changes:
* Added `disableGradualRequestCleaner()` init config support.
Expand All @@ -100,7 +172,7 @@
* Added a new Consent option "metrics" for controlling "recordMetrics" method. (This has no effect on Session metrics.)
* Added event listener calls for new architecture (thanks @j-q-in-berlin)

* Mitigated an issue in SDK limits config class initialization (thanks @albertlaiuste)
* Mitigated an issue in SDK limits config class initialization (thanks @albertlaiuste)

* Android specific changes:
* Improved disk size calculation in crash reports.
Expand Down
Loading
Loading