feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

View File

@@ -0,0 +1,2 @@
// @generated by expo-module-scripts
module.exports = require('expo-module-scripts/eslintrc.base.js');

View File

@@ -0,0 +1,217 @@
# Changelog
## Unpublished
### 🛠 Breaking changes
### 🎉 New features
### 🐛 Bug fixes
### 💡 Others
## 5.9.1 — 2024-04-23
_This version does not introduce any user-facing changes._
## 5.9.0 — 2024-04-18
### 💡 Others
- [iOS] Add privacy manifest describing required reason API usage. ([#27770](https://github.com/expo/expo/pull/27770) by [@aleqsio](https://github.com/aleqsio))
- drop unused web `name` property. ([#27437](https://github.com/expo/expo/pull/27437) by [@EvanBacon](https://github.com/EvanBacon))
- Removed deprecated backward compatible Gradle settings. ([#28083](https://github.com/expo/expo/pull/28083) by [@kudo](https://github.com/kudo))
## 5.8.3 - 2024-01-18
_This version does not introduce any user-facing changes._
## 5.8.2 - 2024-01-10
_This version does not introduce any user-facing changes._
## 5.8.1 - 2023-12-19
_This version does not introduce any user-facing changes._
## 5.8.0 — 2023-12-12
### 🐛 Bug fixes
- On iOS, fixed a regression that prevented expo go from determining the release type. ([#25834](https://github.com/expo/expo/pull/25834) by [@alanjhughes](https://github.com/alanjhughes))
## 5.7.0 — 2023-11-14
### 🛠 Breaking changes
- Bumped iOS deployment target to 13.4. ([#25063](https://github.com/expo/expo/pull/25063) by [@gabrieldonadel](https://github.com/gabrieldonadel))
- On `Android` bump `compileSdkVersion` and `targetSdkVersion` to `34`. ([#24708](https://github.com/expo/expo/pull/24708) by [@alanjhughes](https://github.com/alanjhughes))
### 💡 Others
- Remove `unimodule.json` in favour of `expo-module.config.json`. ([#25100](https://github.com/expo/expo/pull/25100) by [@reichhartd](https://github.com/reichhartd))
## 5.6.0 — 2023-10-17
### 🛠 Breaking changes
- Dropped support for Android SDK 21 and 22. ([#24201](https://github.com/expo/expo/pull/24201) by [@behenate](https://github.com/behenate))
- Removed `androidId` constant in favor of a method (`getAndroidId`) to comply with Huawei and Xiaomi's app store policies. ([#22585](https://github.com/expo/expo/pull/22585) by [@fobos531](https://github.com/fobos531))
### 🎉 New features
- Migrate iOS module to Expo modules API. ([#24871](https://github.com/expo/expo/pull/24871) by [@reichhartd](https://github.com/reichhartd))
- Android module is now written using the Sweet API. ([#22395](https://github.com/expo/expo/pull/22585) by [@fobos531](https://github.com/fobos531))
## 5.5.0 — 2023-09-15
### 🎉 New features
- Added support for Apple tvOS. ([#24329](https://github.com/expo/expo/pull/24329) by [@douglowder](https://github.com/douglowder))
## 5.4.0 — 2023-09-04
### 🎉 New features
- Added support for React Native 0.73. ([#24018](https://github.com/expo/expo/pull/24018) by [@kudo](https://github.com/kudo))
## 5.3.1 — 2023-08-02
_This version does not introduce any user-facing changes._
## 5.3.0 — 2023-06-13
### 📚 3rd party library updates
- Updated `robolectric` to `4.10` and `junit` to `4.13.2`. ([#22395](https://github.com/expo/expo/pull/22395) by [@josephyanks](https://github.com/josephyanks))
### 🐛 Bug fixes
- Fixed Android build warnings for Gradle version 8. ([#22537](https://github.com/expo/expo/pull/22537), [#22609](https://github.com/expo/expo/pull/22609) by [@kudo](https://github.com/kudo))
## 5.2.0 — 2023-05-08
_This version does not introduce any user-facing changes._
## 5.1.1 — 2023-02-09
_This version does not introduce any user-facing changes._
## 5.1.0 — 2023-02-03
### 💡 Others
- On Android bump `compileSdkVersion` and `targetSdkVersion` to `33`. ([#20721](https://github.com/expo/expo/pull/20721) by [@lukmccall](https://github.com/lukmccall))
## 5.0.1 — 2022-10-28
_This version does not introduce any user-facing changes._
## 5.0.0 — 2022-10-06
### 🛠 Breaking changes
- Bumped iOS deployment target to 13.0 and deprecated support for iOS 12. ([#18873](https://github.com/expo/expo/pull/18873) by [@tsapeta](https://github.com/tsapeta))
## 4.2.2 — 2022-07-19
_This version does not introduce any user-facing changes._
## 4.2.1 — 2022-07-18
### 💡 Others
- Clarify that `getIosPushNotificationServiceEnvironmentAsync` returns `null` on the simulator. ([#18282](https://github.com/expo/expo/pull/18282) by [@tsapeta](https://github.com/tsapeta))
## 4.2.0 — 2022-07-07
_This version does not introduce any user-facing changes._
## 4.1.0 — 2022-04-18
### ⚠️ Notices
- On Android bump `compileSdkVersion` to `31`, `targetSdkVersion` to `31` and `Java` version to `11`. ([#16941](https://github.com/expo/expo/pull/16941) by [@bbarthec](https://github.com/bbarthec))
## 4.0.2 - 2022-02-01
### 🐛 Bug fixes
- Fix `Plugin with id 'maven' not found` build error from Android Gradle 7. ([#16080](https://github.com/expo/expo/pull/16080) by [@kudo](https://github.com/kudo))
## 4.0.1 — 2021-11-17
_This version does not introduce any user-facing changes._
## 4.0.0 — 2021-09-28
### 🛠 Breaking changes
- Dropped support for iOS 11.0 ([#14383](https://github.com/expo/expo/pull/14383) by [@cruzach](https://github.com/cruzach))
### 🐛 Bug fixes
- Fix building errors from use_frameworks! in Podfile. ([#14523](https://github.com/expo/expo/pull/14523) by [@kudo](https://github.com/kudo))
## 3.3.0 — 2021-09-08
### 💡 Others
- Rewrite android code to Kotlin ([#13792](https://github.com/expo/expo/pull/13792) by [@kkafar](https://github.com/kkafar))
- Add basic unit tests to Kotlin. ([#13792](https://github.com/expo/expo/pull/13792) by [@kkafar](https://github.com/kkafar))
## 3.2.0 — 2021-06-16
### 🐛 Bug fixes
- Enable kotlin in all modules. ([#12716](https://github.com/expo/expo/pull/12716) by [@wschurman](https://github.com/wschurman))
### 💡 Others
- Build Android code using Java 8 to fix Android instrumented test build error. ([#12939](https://github.com/expo/expo/pull/12939) by [@kudo](https://github.com/kudo))
## 3.1.2 — 2021-04-13
_This version does not introduce any user-facing changes._
## 3.1.1 — 2021-04-09
_This version does not introduce any user-facing changes._
## 3.1.0 — 2021-03-10
### 🎉 New features
- Updated Android build configuration to target Android 11 (added support for Android SDK 30). ([#11647](https://github.com/expo/expo/pull/11647) by [@bbarthec](https://github.com/bbarthec))
### 🐛 Bug fixes
- Remove peerDependencies and unimodulePeerDependencies from Expo modules. ([#11980](https://github.com/expo/expo/pull/11980) by [@brentvatne](https://github.com/brentvatne))
## 3.0.0 — 2021-01-15
### 🛠 Breaking changes
- Dropped support for iOS 10.0 ([#11344](https://github.com/expo/expo/pull/11344) by [@tsapeta](https://github.com/tsapeta))
## 2.4.1 — 2020-11-25
### 🐛 Bug fixes
- Fixed return type of `getIosIdForVendorAsync` to include possible `null` value which can be returned if the device hasn't been unlocked yet (for more information consult the [Apple documentation for `identifierForVendor`](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor?language=objc)). ([#10997](https://github.com/expo/expo/pull/10997) by [@sjchmiela](https://github.com/sjchmiela))
## 2.4.0 — 2020-11-17
_This version does not introduce any user-facing changes._
## 2.3.0 — 2020-08-18
_This version does not introduce any user-facing changes._
## 2.2.1 — 2020-05-28
_This version does not introduce any user-facing changes._
## 2.2.0 — 2020-05-27
_This version does not introduce any user-facing changes._

View File

@@ -0,0 +1,25 @@
# expo-application
Gets native application information such as its ID, app name, and build version at runtime.
# API documentation
- [Documentation for the main branch](https://github.com/expo/expo/blob/main/docs/pages/versions/unversioned/sdk/application.md)
# Installation in managed Expo projects
For [managed](https://docs.expo.dev/archive/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](#https://docs.expo.dev/versions/latest/sdk/application/).
# Installation in bare React Native projects
For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
### Add the package to your npm dependencies
```
npx expo install expo-application
```
# Contributing
Contributions are very welcome! Please refer to guidelines described in the [contributing guide](https://github.com/expo/expo#contributing).

View File

@@ -0,0 +1,29 @@
apply plugin: 'com.android.library'
group = 'host.exp.exponent'
version = '5.9.1'
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
apply from: expoModulesCorePlugin
applyKotlinExpoModulesCorePlugin()
useCoreDependencies()
useDefaultAndroidSdkVersions()
useExpoPublishing()
android {
namespace "expo.modules.application"
defaultConfig {
versionCode 12
versionName '5.9.1'
}
}
dependencies {
implementation 'com.android.installreferrer:installreferrer:2.2'
if (project.findProject(':expo-modules-test-core')) {
testImplementation project(':expo-modules-test-core')
}
testImplementation "org.robolectric:robolectric:4.10"
testImplementation 'junit:junit:4.13.2'
}

View File

@@ -0,0 +1,2 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View File

@@ -0,0 +1,127 @@
package expo.modules.application
import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.os.Build
import android.os.RemoteException
import android.provider.Settings
import com.android.installreferrer.api.InstallReferrerClient
import com.android.installreferrer.api.InstallReferrerStateListener
import expo.modules.kotlin.Promise
import expo.modules.kotlin.exception.CodedException
import expo.modules.kotlin.exception.Exceptions
import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
class ApplicationPackageNameNotFoundException(cause: PackageManager.NameNotFoundException) :
CodedException(message = "Unable to get install time of this application. Could not get package info or package name.", cause = cause)
class ApplicationModule : Module() {
private val context: Context
get() = appContext.reactContext ?: throw Exceptions.ReactContextLost()
override fun definition() = ModuleDefinition {
Name("ExpoApplication")
Constants {
return@Constants mapOf(
"applicationName" to applicationName,
"applicationId" to packageName,
"nativeApplicationVersion" to versionName,
"nativeBuildVersion" to versionCode.toString()
)
}
Property("androidId") {
Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
}
AsyncFunction<Double>("getInstallationTimeAsync") {
val packageManager = context.packageManager
val packageName = context.packageName
packageManager
.getPackageInfoCompat(packageName, 0)
.firstInstallTime
.toDouble()
}
AsyncFunction<Double>("getLastUpdateTimeAsync") {
val packageManager = context.packageManager
val packageName = context.packageName
packageManager
.getPackageInfoCompat(packageName, 0)
.lastUpdateTime
.toDouble()
}
AsyncFunction("getInstallReferrerAsync") { promise: Promise ->
val installReferrer = StringBuilder()
val referrerClient = InstallReferrerClient.newBuilder(context).build()
referrerClient.startConnection(object : InstallReferrerStateListener {
override fun onInstallReferrerSetupFinished(responseCode: Int) {
when (responseCode) {
InstallReferrerClient.InstallReferrerResponse.OK -> {
// Connection established and response received
try {
val response = referrerClient.installReferrer
installReferrer.append(response.installReferrer)
} catch (e: RemoteException) {
promise.reject("ERR_APPLICATION_INSTALL_REFERRER_REMOTE_EXCEPTION", "RemoteException getting install referrer information. This may happen if the process hosting the remote object is no longer available.", e)
return
}
promise.resolve(installReferrer.toString())
}
InstallReferrerClient.InstallReferrerResponse.FEATURE_NOT_SUPPORTED -> // API not available in the current Play Store app
promise.reject("ERR_APPLICATION_INSTALL_REFERRER_UNAVAILABLE", "The current Play Store app doesn't provide the installation referrer API, or the Play Store may not be installed.", null)
InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE -> // Connection could not be established
promise.reject("ERR_APPLICATION_INSTALL_REFERRER", "General error retrieving the install referrer: response code $responseCode", null)
else -> promise.reject("ERR_APPLICATION_INSTALL_REFERRER", "General error retrieving the install referrer: response code $responseCode", null)
}
referrerClient.endConnection()
}
override fun onInstallReferrerServiceDisconnected() {
promise.reject("ERR_APPLICATION_INSTALL_REFERRER_SERVICE_DISCONNECTED", "Connection to install referrer service was lost.", null)
}
})
}
}
private val applicationName
get() = context.applicationInfo.loadLabel(context.packageManager).toString()
private val packageName
get() = context.packageName
private val packageManager
get() = context.packageManager
private val versionName
get() = packageManager.getPackageInfoCompat(packageName, 0).versionName
private val versionCode
get() = getLongVersionCode(packageManager.getPackageInfoCompat(packageName, 0)).toInt()
}
private fun PackageManager.getPackageInfoCompat(packageName: String, flags: Int = 0): PackageInfo =
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(flags.toLong()))
} else {
@Suppress("DEPRECATION")
getPackageInfo(packageName, flags)
}
} catch (e: PackageManager.NameNotFoundException) {
throw ApplicationPackageNameNotFoundException(e)
}
private fun getLongVersionCode(info: PackageInfo): Long {
return if (Build.VERSION.SDK_INT >= 28) {
info.longVersionCode
} else {
@Suppress("DEPRECATION")
info.versionCode.toLong()
}
}

View File

@@ -0,0 +1,131 @@
import { ApplicationReleaseType, PushNotificationServiceEnvironment } from './Application.types';
/**
* The human-readable version of the native application that may be displayed in the app store.
* This is the `Info.plist` value for `CFBundleShortVersionString` on iOS and the version name set
* by `version` in `app.json` on Android at the time the native app was built.
* On web, this value is `null`.
* @example
* `"2.11.0"`
*/
export declare const nativeApplicationVersion: string | null;
/**
* The internal build version of the native application that the app store may use to distinguish
* between different binaries. This is the `Info.plist` value for `CFBundleVersion` on iOS (set with
* `ios.buildNumber` value in `app.json` in a standalone app) and the version code set by
* `android.versionCode` in `app.json` on Android at the time the native app was built. On web, this
* value is `null`. The return type on Android and iOS is `string`.
* @example
* Android: `"114"`, iOS: `"2.11.0"`
*/
export declare const nativeBuildVersion: string | null;
/**
* The human-readable name of the application that is displayed with the app's icon on the device's
* home screen or desktop. On Android and iOS, this value is a `string` unless the name could not be
* retrieved, in which case this value will be `null`. On web this value is `null`.
* @example
* `"Expo"`, `"Yelp"`, `"Instagram"`
*/
export declare const applicationName: string | null;
/**
* The ID of the application. On Android, this is the application ID. On iOS, this is the bundle ID.
* On web, this is `null`.
* @example
* `"com.cocoacasts.scribbles"`, `"com.apple.Pages"`
*/
export declare const applicationId: string | null;
/**
* Gets the value of [`Settings.Secure.ANDROID_ID`](https://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID).
* This is a hexadecimal `string` unique to each combination of app-signing key, user, and device.
* The value may change if a factory reset is performed on the device or if an APK signing key changes.
* For more information about how the platform handles `ANDROID_ID` in Android 8.0 (API level 26)
* and higher, see [Android 8.0 Behavior Changes](https://developer.android.com/about/versions/oreo/android-8.0-changes.html#privacy-all).
* On iOS and web, this function is unavailable.
* > In versions of the platform lower than Android 8.0 (API level 26), this value remains constant
* > for the lifetime of the user's device. See the [ANDROID_ID](https://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID)
* > official docs for more information.
* @example
* `"dd96dec43fb81c97"`
* @platform android
*/
export declare function getAndroidId(): string;
/**
* Gets the referrer URL of the installed app with the [`Install Referrer API`](https://developer.android.com/google/play/installreferrer)
* from the Google Play Store. In practice, the referrer URL may not be a complete, absolute URL.
* @return A `Promise` that fulfills with a `string` of the referrer URL of the installed app.
*
* @example
* ```ts
* await Application.getInstallReferrerAsync();
* // "utm_source=google-play&utm_medium=organic"
* ```
* @platform android
*/
export declare function getInstallReferrerAsync(): Promise<string>;
/**
* Gets the iOS "identifier for vendor" ([IDFV](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor))
* value, a string ID that uniquely identifies a device to the apps vendor. This method may
* sometimes return `nil`, in which case wait and call the method again later. This might happen
* when the device has been restarted before the user has unlocked the device.
*
* The OS will change the vendor identifier if all apps from the current app's vendor have been
* uninstalled.
*
* @return A `Promise` that fulfills with a `string` specifying the app's vendor ID. Apps from the
* same vendor will return the same ID. See Apple's documentation for more information about the
* vendor ID's semantics.
*
* @example
* ```ts
* await Application.getIosIdForVendorAsync();
* // "68753A44-4D6F-1226-9C60-0050E4C00067"
* ```
* @platform ios
*/
export declare function getIosIdForVendorAsync(): Promise<string | null>;
/**
* Gets the iOS application release type.
* @return Returns a promise which fulfills with an [`ApplicationReleaseType`](#applicationreleasetype).
* @platform ios
*/
export declare function getIosApplicationReleaseTypeAsync(): Promise<ApplicationReleaseType>;
/**
* Gets the current [Apple Push Notification (APN)](https://developer.apple.com/documentation/bundleresources/entitlements/aps-environment?language=objc)
* service environment.
* @return Returns a promise fulfilled with the string, either `'development'` or `'production'`,
* based on the current APN environment, or `null` on the simulator as it does not support registering with APNs.
* @platform ios
*/
export declare function getIosPushNotificationServiceEnvironmentAsync(): Promise<PushNotificationServiceEnvironment>;
/**
* Gets the time the app was installed onto the device, not counting subsequent updates. If the app
* is uninstalled and reinstalled, this method returns the time the app was reinstalled.
* - On iOS, this method uses the [`NSFileCreationDate`](https://developer.apple.com/documentation/foundation/nsfilecreationdate?language=objc)
* of the app's document root directory.
* - On Android, this method uses [`PackageInfo.firstInstallTime`](https://developer.android.com/reference/android/content/pm/PackageInfo.html#firstInstallTime).
* - On web, this method returns `null`.
*
* @return Returns a `Promise` that fulfills with a `Date` object that specifies the time the app
* was installed on the device.
*
* @example
* ```ts
* await Application.getInstallationTimeAsync();
* // 2019-07-18T18:08:26.121Z
* ```
*/
export declare function getInstallationTimeAsync(): Promise<Date>;
/**
* Gets the last time the app was updated from the Google Play Store.
* @return Returns a `Promise` that fulfills with a `Date` object that specifies the last time
* the app was updated via the Google Play Store).
*
* @example
* ```ts
* await Application.getLastUpdateTimeAsync();
* // 2019-07-18T21:20:16.887Z
* ```
* @platform android
*/
export declare function getLastUpdateTimeAsync(): Promise<Date>;
export { ApplicationReleaseType, PushNotificationServiceEnvironment };
//# sourceMappingURL=Application.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../src/Application.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,kCAAkC,EAAE,MAAM,qBAAqB,CAAC;AAIjG;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,GAAG,IAExC,CAAC;AAGT;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,GAAG,IAElC,CAAC;AAGT;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,GAAG,IAE/B,CAAC;AAGT;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,GAAG,IAE7B,CAAC;AAGT;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAGD;;;;;;;;;;;GAWG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC,CAK/D;AAGD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAKrE;AAGD;;;;GAIG;AACH,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAKzF;AAGD;;;;;;GAMG;AACH,wBAAsB,6CAA6C,IAAI,OAAO,CAAC,kCAAkC,CAAC,CAKjH;AAGD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9D;AAGD;;;;;;;;;;;GAWG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM5D;AAED,OAAO,EAAE,sBAAsB,EAAE,kCAAkC,EAAE,CAAC"}

View File

@@ -0,0 +1,189 @@
import { Platform, UnavailabilityError } from 'expo-modules-core';
import { ApplicationReleaseType } from './Application.types';
import ExpoApplication from './ExpoApplication';
// @needsAudit
/**
* The human-readable version of the native application that may be displayed in the app store.
* This is the `Info.plist` value for `CFBundleShortVersionString` on iOS and the version name set
* by `version` in `app.json` on Android at the time the native app was built.
* On web, this value is `null`.
* @example
* `"2.11.0"`
*/
export const nativeApplicationVersion = ExpoApplication
? ExpoApplication.nativeApplicationVersion || null
: null;
// @needsAudit
/**
* The internal build version of the native application that the app store may use to distinguish
* between different binaries. This is the `Info.plist` value for `CFBundleVersion` on iOS (set with
* `ios.buildNumber` value in `app.json` in a standalone app) and the version code set by
* `android.versionCode` in `app.json` on Android at the time the native app was built. On web, this
* value is `null`. The return type on Android and iOS is `string`.
* @example
* Android: `"114"`, iOS: `"2.11.0"`
*/
export const nativeBuildVersion = ExpoApplication
? ExpoApplication.nativeBuildVersion || null
: null;
// @needsAudit
/**
* The human-readable name of the application that is displayed with the app's icon on the device's
* home screen or desktop. On Android and iOS, this value is a `string` unless the name could not be
* retrieved, in which case this value will be `null`. On web this value is `null`.
* @example
* `"Expo"`, `"Yelp"`, `"Instagram"`
*/
export const applicationName = ExpoApplication
? ExpoApplication.applicationName || null
: null;
// @needsAudit
/**
* The ID of the application. On Android, this is the application ID. On iOS, this is the bundle ID.
* On web, this is `null`.
* @example
* `"com.cocoacasts.scribbles"`, `"com.apple.Pages"`
*/
export const applicationId = ExpoApplication
? ExpoApplication.applicationId || null
: null;
// @needsAudit
/**
* Gets the value of [`Settings.Secure.ANDROID_ID`](https://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID).
* This is a hexadecimal `string` unique to each combination of app-signing key, user, and device.
* The value may change if a factory reset is performed on the device or if an APK signing key changes.
* For more information about how the platform handles `ANDROID_ID` in Android 8.0 (API level 26)
* and higher, see [Android 8.0 Behavior Changes](https://developer.android.com/about/versions/oreo/android-8.0-changes.html#privacy-all).
* On iOS and web, this function is unavailable.
* > In versions of the platform lower than Android 8.0 (API level 26), this value remains constant
* > for the lifetime of the user's device. See the [ANDROID_ID](https://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID)
* > official docs for more information.
* @example
* `"dd96dec43fb81c97"`
* @platform android
*/
export function getAndroidId() {
if (Platform.OS !== 'android') {
throw new UnavailabilityError('expo-application', 'androidId');
}
return ExpoApplication.androidId;
}
// @needsAudit
/**
* Gets the referrer URL of the installed app with the [`Install Referrer API`](https://developer.android.com/google/play/installreferrer)
* from the Google Play Store. In practice, the referrer URL may not be a complete, absolute URL.
* @return A `Promise` that fulfills with a `string` of the referrer URL of the installed app.
*
* @example
* ```ts
* await Application.getInstallReferrerAsync();
* // "utm_source=google-play&utm_medium=organic"
* ```
* @platform android
*/
export async function getInstallReferrerAsync() {
if (!ExpoApplication.getInstallReferrerAsync) {
throw new UnavailabilityError('expo-application', 'getInstallReferrerAsync');
}
return await ExpoApplication.getInstallReferrerAsync();
}
// @needsAudit
/**
* Gets the iOS "identifier for vendor" ([IDFV](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor))
* value, a string ID that uniquely identifies a device to the apps vendor. This method may
* sometimes return `nil`, in which case wait and call the method again later. This might happen
* when the device has been restarted before the user has unlocked the device.
*
* The OS will change the vendor identifier if all apps from the current app's vendor have been
* uninstalled.
*
* @return A `Promise` that fulfills with a `string` specifying the app's vendor ID. Apps from the
* same vendor will return the same ID. See Apple's documentation for more information about the
* vendor ID's semantics.
*
* @example
* ```ts
* await Application.getIosIdForVendorAsync();
* // "68753A44-4D6F-1226-9C60-0050E4C00067"
* ```
* @platform ios
*/
export async function getIosIdForVendorAsync() {
if (!ExpoApplication.getIosIdForVendorAsync) {
throw new UnavailabilityError('expo-application', 'getIosIdForVendorAsync');
}
return await ExpoApplication.getIosIdForVendorAsync();
}
// @needsAudit
/**
* Gets the iOS application release type.
* @return Returns a promise which fulfills with an [`ApplicationReleaseType`](#applicationreleasetype).
* @platform ios
*/
export async function getIosApplicationReleaseTypeAsync() {
if (!ExpoApplication.getApplicationReleaseTypeAsync) {
throw new UnavailabilityError('expo-application', 'getApplicationReleaseTypeAsync');
}
return await ExpoApplication.getApplicationReleaseTypeAsync();
}
// @needsAudit
/**
* Gets the current [Apple Push Notification (APN)](https://developer.apple.com/documentation/bundleresources/entitlements/aps-environment?language=objc)
* service environment.
* @return Returns a promise fulfilled with the string, either `'development'` or `'production'`,
* based on the current APN environment, or `null` on the simulator as it does not support registering with APNs.
* @platform ios
*/
export async function getIosPushNotificationServiceEnvironmentAsync() {
if (!ExpoApplication.getPushNotificationServiceEnvironmentAsync) {
throw new UnavailabilityError('expo-application', 'getPushNotificationServiceEnvironmentAsync');
}
return await ExpoApplication.getPushNotificationServiceEnvironmentAsync();
}
// @needsAudit
/**
* Gets the time the app was installed onto the device, not counting subsequent updates. If the app
* is uninstalled and reinstalled, this method returns the time the app was reinstalled.
* - On iOS, this method uses the [`NSFileCreationDate`](https://developer.apple.com/documentation/foundation/nsfilecreationdate?language=objc)
* of the app's document root directory.
* - On Android, this method uses [`PackageInfo.firstInstallTime`](https://developer.android.com/reference/android/content/pm/PackageInfo.html#firstInstallTime).
* - On web, this method returns `null`.
*
* @return Returns a `Promise` that fulfills with a `Date` object that specifies the time the app
* was installed on the device.
*
* @example
* ```ts
* await Application.getInstallationTimeAsync();
* // 2019-07-18T18:08:26.121Z
* ```
*/
export async function getInstallationTimeAsync() {
if (!ExpoApplication.getInstallationTimeAsync) {
throw new UnavailabilityError('expo-application', 'getInstallationTimeAsync');
}
const installationTime = await ExpoApplication.getInstallationTimeAsync();
return new Date(installationTime);
}
// @needsAudit
/**
* Gets the last time the app was updated from the Google Play Store.
* @return Returns a `Promise` that fulfills with a `Date` object that specifies the last time
* the app was updated via the Google Play Store).
*
* @example
* ```ts
* await Application.getLastUpdateTimeAsync();
* // 2019-07-18T21:20:16.887Z
* ```
* @platform android
*/
export async function getLastUpdateTimeAsync() {
if (!ExpoApplication.getLastUpdateTimeAsync) {
throw new UnavailabilityError('expo-application', 'getLastUpdateTimeAsync');
}
const lastUpdateTime = await ExpoApplication.getLastUpdateTimeAsync();
return new Date(lastUpdateTime);
}
export { ApplicationReleaseType };
//# sourceMappingURL=Application.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
export declare enum ApplicationReleaseType {
UNKNOWN = 0,
SIMULATOR = 1,
ENTERPRISE = 2,
DEVELOPMENT = 3,
AD_HOC = 4,
APP_STORE = 5
}
/**
* Maps to the [`aps-environment`](https://developer.apple.com/documentation/bundleresources/entitlements/aps-environment) key in the native target's registered entitlements.
*/
export type PushNotificationServiceEnvironment = 'development' | 'production' | null;
//# sourceMappingURL=Application.types.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Application.types.d.ts","sourceRoot":"","sources":["../src/Application.types.ts"],"names":[],"mappings":"AACA,oBAAY,sBAAsB;IAChC,OAAO,IAAI;IACX,SAAS,IAAI;IACb,UAAU,IAAI;IACd,WAAW,IAAI;IACf,MAAM,IAAI;IACV,SAAS,IAAI;CACd;AAED;;GAEG;AACH,MAAM,MAAM,kCAAkC,GAAG,aAAa,GAAG,YAAY,GAAG,IAAI,CAAC"}

View File

@@ -0,0 +1,11 @@
// @docsMissing
export var ApplicationReleaseType;
(function (ApplicationReleaseType) {
ApplicationReleaseType[ApplicationReleaseType["UNKNOWN"] = 0] = "UNKNOWN";
ApplicationReleaseType[ApplicationReleaseType["SIMULATOR"] = 1] = "SIMULATOR";
ApplicationReleaseType[ApplicationReleaseType["ENTERPRISE"] = 2] = "ENTERPRISE";
ApplicationReleaseType[ApplicationReleaseType["DEVELOPMENT"] = 3] = "DEVELOPMENT";
ApplicationReleaseType[ApplicationReleaseType["AD_HOC"] = 4] = "AD_HOC";
ApplicationReleaseType[ApplicationReleaseType["APP_STORE"] = 5] = "APP_STORE";
})(ApplicationReleaseType || (ApplicationReleaseType = {}));
//# sourceMappingURL=Application.types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Application.types.js","sourceRoot":"","sources":["../src/Application.types.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,MAAM,CAAN,IAAY,sBAOX;AAPD,WAAY,sBAAsB;IAChC,yEAAW,CAAA;IACX,6EAAa,CAAA;IACb,+EAAc,CAAA;IACd,iFAAe,CAAA;IACf,uEAAU,CAAA;IACV,6EAAa,CAAA;AACf,CAAC,EAPW,sBAAsB,KAAtB,sBAAsB,QAOjC","sourcesContent":["// @docsMissing\nexport enum ApplicationReleaseType {\n UNKNOWN = 0,\n SIMULATOR = 1,\n ENTERPRISE = 2,\n DEVELOPMENT = 3,\n AD_HOC = 4,\n APP_STORE = 5,\n}\n\n/**\n * Maps to the [`aps-environment`](https://developer.apple.com/documentation/bundleresources/entitlements/aps-environment) key in the native target's registered entitlements.\n */\nexport type PushNotificationServiceEnvironment = 'development' | 'production' | null;\n"]}

View File

@@ -0,0 +1,3 @@
declare const _default: any;
export default _default;
//# sourceMappingURL=ExpoApplication.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ExpoApplication.d.ts","sourceRoot":"","sources":["../src/ExpoApplication.ts"],"names":[],"mappings":";AAEA,wBAAsD"}

View File

@@ -0,0 +1,3 @@
import { requireNativeModule } from 'expo-modules-core';
export default requireNativeModule('ExpoApplication');
//# sourceMappingURL=ExpoApplication.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ExpoApplication.js","sourceRoot":"","sources":["../src/ExpoApplication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,eAAe,mBAAmB,CAAC,iBAAiB,CAAC,CAAC","sourcesContent":["import { requireNativeModule } from 'expo-modules-core';\n\nexport default requireNativeModule('ExpoApplication');\n"]}

View File

@@ -0,0 +1,10 @@
declare const _default: {
readonly applicationName: null;
readonly bundleId: null;
readonly nativeApplicationVersion: null;
readonly nativeBuildVersion: null;
readonly androidId: null;
getInstallationTimeAsync(): Promise<null>;
};
export default _default;
//# sourceMappingURL=ExpoApplication.web.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ExpoApplication.web.d.ts","sourceRoot":"","sources":["../src/ExpoApplication.web.ts"],"names":[],"mappings":";;;;;;gCAgBoC,QAAQ,IAAI,CAAC;;AAhBjD,wBAmBE"}

View File

@@ -0,0 +1,21 @@
export default {
get applicationName() {
return null;
},
get bundleId() {
return null;
},
get nativeApplicationVersion() {
return null;
},
get nativeBuildVersion() {
return null;
},
get androidId() {
return null;
},
async getInstallationTimeAsync() {
return null;
},
};
//# sourceMappingURL=ExpoApplication.web.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ExpoApplication.web.js","sourceRoot":"","sources":["../src/ExpoApplication.web.ts"],"names":[],"mappings":"AAAA,eAAe;IACb,IAAI,eAAe;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,wBAAwB;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,kBAAkB;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,SAAS;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IACD,KAAK,CAAC,wBAAwB;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC","sourcesContent":["export default {\n get applicationName(): null {\n return null;\n },\n get bundleId(): null {\n return null;\n },\n get nativeApplicationVersion(): null {\n return null;\n },\n get nativeBuildVersion(): null {\n return null;\n },\n get androidId(): null {\n return null;\n },\n async getInstallationTimeAsync(): Promise<null> {\n return null;\n },\n};\n"]}

View File

@@ -0,0 +1,9 @@
{
"platforms": ["apple", "android", "web"],
"apple": {
"modules": ["ApplicationModule"]
},
"android": {
"modules": ["expo.modules.application.ApplicationModule"]
}
}

View File

@@ -0,0 +1,19 @@
import ExpoModulesCore
internal class UrlDocumentDirectoryException: Exception {
override var reason: String {
"Unable to get url for document directory"
}
}
internal class InstallationTimeException: Exception {
override var reason: String {
"Unable to get installation time of this application"
}
}
internal class DateCastException: Exception {
override var reason: String {
"Invalid date format"
}
}

View File

@@ -0,0 +1,49 @@
// Copyright 2018-present 650 Industries. All rights reserved.
import ExpoModulesCore
public class ApplicationModule: Module {
public func definition() -> ModuleDefinition {
Name("ExpoApplication")
Constants {
let infoPlist = Bundle.main.infoDictionary
return [
"applicationName": infoPlist?["CFBundleDisplayName"],
"applicationId": infoPlist?["CFBundleIdentifier"],
"nativeApplicationVersion": infoPlist?["CFBundleShortVersionString"],
"nativeBuildVersion": infoPlist?["CFBundleVersion"]
]
}
AsyncFunction("getIosIdForVendorAsync") { () -> String? in
return UIDevice.current.identifierForVendor?.uuidString
}
AsyncFunction("getInstallationTimeAsync") { () -> Double in
guard let urlToDocumentsFolder = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last else {
throw UrlDocumentDirectoryException()
}
do {
let fileAttributes = try FileManager.default.attributesOfItem(atPath: urlToDocumentsFolder.path)
// Uses required reason API based on the following reason: C617.1
if let installDate = fileAttributes[FileAttributeKey.creationDate] as? Date {
return installDate.timeIntervalSince1970 * 1000
}
throw DateCastException()
} catch {
throw InstallationTimeException()
}
}
AsyncFunction("getApplicationReleaseTypeAsync") { () -> Int in
let mainProvisioningProfile = EXProvisioningProfile.main()
return mainProvisioningProfile.appReleaseType().rawValue
}
AsyncFunction("getPushNotificationServiceEnvironmentAsync") { () -> String? in
let mainProvisioningProfile = EXProvisioningProfile.main()
return mainProvisioningProfile.notificationServiceEnvironment()
}
}
}

View File

@@ -0,0 +1,34 @@
require 'json'
package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
Pod::Spec.new do |s|
s.name = 'EXApplication'
s.version = package['version']
s.summary = package['description']
s.description = package['description']
s.license = package['license']
s.author = package['author']
s.homepage = package['homepage']
s.platforms = { :ios => '13.4', :tvos => '13.4'}
s.swift_version = '5.4'
s.source = { git: 'https://github.com/expo/expo.git' }
s.static_framework = true
s.dependency 'ExpoModulesCore'
# Swift/Objective-C compatibility
s.pod_target_xcconfig = {
'DEFINES_MODULE' => 'YES',
'SWIFT_COMPILATION_MODE' => 'wholemodule'
}
s.resource_bundles = {'ExpoApplication_privacy' => ['PrivacyInfo.xcprivacy']}
if !$ExpoUseSources&.include?(package['name']) && ENV['EXPO_USE_SOURCE'].to_i == 0 && File.exist?("#{s.name}.xcframework") && Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
s.source_files = "#{s.name}/**/*.h"
s.vendored_frameworks = "#{s.name}.xcframework"
else
s.source_files = "**/*.{h,m,swift}"
end
end

View File

@@ -0,0 +1,22 @@
// Copyright 2015-present 650 Industries. All rights reserved.
#import <Foundation/Foundation.h>
// Keep in sync with ApplicationReleaseType in JS
typedef NS_ENUM(NSInteger, EXAppReleaseType) {
EXAppReleaseTypeUnknown,
EXAppReleaseSimulator,
EXAppReleaseEnterprise,
EXAppReleaseDev,
EXAppReleaseAdHoc,
EXAppReleaseAppStore
};
@interface EXProvisioningProfile : NSObject
+ (nonnull instancetype)mainProvisioningProfile;
- (EXAppReleaseType)appReleaseType;
- (nullable NSString *)notificationServiceEnvironment;
@end

View File

@@ -0,0 +1,134 @@
// Copyright 2015-present 650 Industries. All rights reserved.
#import "EXProvisioningProfile.h"
@implementation EXProvisioningProfile {
NSDictionary *_plist;
}
+ (nonnull instancetype)mainProvisioningProfile
{
static EXProvisioningProfile *profile;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSDictionary *plist = [self _readProvisioningProfilePlist];
profile = [[self alloc] initWithPlist:plist];
});
return profile;
}
- (instancetype)initWithPlist:(NSDictionary *)plist
{
if (self = [super init]) {
_plist = plist;
}
return self;
}
- (nullable NSString *)notificationServiceEnvironment
{
if (!_plist) {
return nil;
}
NSDictionary *entitlements = _plist[@"Entitlements"];
NSString *apsEnvironment = entitlements[@"aps-environment"];
return apsEnvironment;
}
- (EXAppReleaseType)appReleaseType {
NSString *provisioningPath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"];
if (!provisioningPath) {
// provisioning profile does not exist
#if TARGET_IPHONE_SIMULATOR
return EXAppReleaseSimulator;
#else
return EXAppReleaseAppStore;
#endif
}
NSDictionary *mobileProvision = _plist;
if (!mobileProvision) {
// failure to read other than it simply not existing
return EXAppReleaseTypeUnknown;
} else if ([[mobileProvision objectForKey:@"ProvisionsAllDevices"] boolValue]) {
// enterprise distribution contains ProvisionsAllDevices - true
return EXAppReleaseEnterprise;
} else if ([mobileProvision objectForKey:@"ProvisionedDevices"] && [[mobileProvision objectForKey:@"ProvisionedDevices"] count] > 0) {
// development contains UDIDs and get-task-allow is true
// ad hoc contains UDIDs and get-task-allow is false
NSDictionary *entitlements = [mobileProvision objectForKey:@"Entitlements"];
if ([[entitlements objectForKey:@"get-task-allow"] boolValue]) {
return EXAppReleaseDev;
} else {
return EXAppReleaseAdHoc;
}
} else {
// app store contains no UDIDs (if the file exists at all?)
return EXAppReleaseAppStore;
}
}
/** embedded.mobileprovision plist format:
AppIDName, // string TextDetective
ApplicationIdentifierPrefix[], // [ string - 66PK3K3KEV ]
CreationData, // date 2013-01-17T14:18:05Z
DeveloperCertificates[], // [ data ]
Entitlements {
application-identifier // string - 66PK3K3KEV.com.blindsight.textdetective
get-task-allow // true or false
keychain-access-groups[] // [ string - 66PK3K3KEV.* ]
},
ExpirationDate, // date 2014-01-17T14:18:05Z
Name, // string Barrierefreikommunizieren (name assigned to the provisioning profile used)
ProvisionedDevices[], // [ string.... ]
TeamIdentifier[], // [string HHBT96X2EX ]
TeamName, // string The Blindsight Corporation
TimeToLive, // integer - 365
UUID, // string 79F37E8E-CC8D-4819-8C13-A678479211CE
Version, // integer 1
ProvisionsAllDevices // true or false ***NB: not sure if this is where this is
*/
+ (NSDictionary *)_readProvisioningProfilePlist
{
NSString *profilePath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"];
if (!profilePath) {
return nil;
}
NSError *error;
NSString *profileString = [NSString stringWithContentsOfFile:profilePath encoding:NSASCIIStringEncoding error:&error];
if (!profileString) {
NSLog(@"Error reading provisioning profile: %@", error.localizedDescription);
return nil;
}
NSScanner *scanner = [NSScanner scannerWithString:profileString];
BOOL readPrelude = [scanner scanUpToString:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" intoString:nil];
if (!readPrelude) {
return nil;
}
NSString *plistString;
BOOL readPlist = [scanner scanUpToString:@"</plist>" intoString:&plistString];
if (!readPlist) {
return nil;
}
plistString = [plistString stringByAppendingString:@"</plist>"];
NSData *plistData = [plistString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *plistDictionary = [NSPropertyListSerialization propertyListWithData:plistData
options:NSPropertyListImmutable
format:NULL
error:&error];
if (!plistDictionary) {
NSLog(@"Error unserializing provisioning profile plist: %@", error.localizedDescription);
return nil;
}
return plistDictionary;
}
@end

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyCollectedDataTypes</key>
<array>
</array>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyTrackingDomains</key>
<array/>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,40 @@
{
"name": "expo-application",
"version": "5.9.1",
"description": "A universal module that gets native application information such as its ID, app name, and build version at runtime",
"main": "build/Application.js",
"types": "build/Application.d.ts",
"scripts": {
"build": "expo-module build",
"clean": "expo-module clean",
"lint": "expo-module lint",
"test": "expo-module test",
"prepare": "expo-module prepare",
"prepublishOnly": "expo-module prepublishOnly",
"expo-module": "expo-module"
},
"keywords": [
"react-native",
"expo",
"expo-application"
],
"repository": {
"type": "git",
"url": "https://github.com/expo/expo.git",
"directory": "packages/expo-application"
},
"bugs": {
"url": "https://github.com/expo/expo/issues"
},
"author": "650 Industries, Inc.",
"license": "MIT",
"homepage": "https://docs.expo.dev/versions/latest/sdk/application/",
"dependencies": {},
"devDependencies": {
"expo-module-scripts": "^3.0.0"
},
"peerDependencies": {
"expo": "*"
},
"gitHead": "ee4f30ef3b5fa567ad1bf94794197f7683fdd481"
}

View File

View File

@@ -0,0 +1,201 @@
import { Platform, UnavailabilityError } from 'expo-modules-core';
import { ApplicationReleaseType, PushNotificationServiceEnvironment } from './Application.types';
import ExpoApplication from './ExpoApplication';
// @needsAudit
/**
* The human-readable version of the native application that may be displayed in the app store.
* This is the `Info.plist` value for `CFBundleShortVersionString` on iOS and the version name set
* by `version` in `app.json` on Android at the time the native app was built.
* On web, this value is `null`.
* @example
* `"2.11.0"`
*/
export const nativeApplicationVersion: string | null = ExpoApplication
? ExpoApplication.nativeApplicationVersion || null
: null;
// @needsAudit
/**
* The internal build version of the native application that the app store may use to distinguish
* between different binaries. This is the `Info.plist` value for `CFBundleVersion` on iOS (set with
* `ios.buildNumber` value in `app.json` in a standalone app) and the version code set by
* `android.versionCode` in `app.json` on Android at the time the native app was built. On web, this
* value is `null`. The return type on Android and iOS is `string`.
* @example
* Android: `"114"`, iOS: `"2.11.0"`
*/
export const nativeBuildVersion: string | null = ExpoApplication
? ExpoApplication.nativeBuildVersion || null
: null;
// @needsAudit
/**
* The human-readable name of the application that is displayed with the app's icon on the device's
* home screen or desktop. On Android and iOS, this value is a `string` unless the name could not be
* retrieved, in which case this value will be `null`. On web this value is `null`.
* @example
* `"Expo"`, `"Yelp"`, `"Instagram"`
*/
export const applicationName: string | null = ExpoApplication
? ExpoApplication.applicationName || null
: null;
// @needsAudit
/**
* The ID of the application. On Android, this is the application ID. On iOS, this is the bundle ID.
* On web, this is `null`.
* @example
* `"com.cocoacasts.scribbles"`, `"com.apple.Pages"`
*/
export const applicationId: string | null = ExpoApplication
? ExpoApplication.applicationId || null
: null;
// @needsAudit
/**
* Gets the value of [`Settings.Secure.ANDROID_ID`](https://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID).
* This is a hexadecimal `string` unique to each combination of app-signing key, user, and device.
* The value may change if a factory reset is performed on the device or if an APK signing key changes.
* For more information about how the platform handles `ANDROID_ID` in Android 8.0 (API level 26)
* and higher, see [Android 8.0 Behavior Changes](https://developer.android.com/about/versions/oreo/android-8.0-changes.html#privacy-all).
* On iOS and web, this function is unavailable.
* > In versions of the platform lower than Android 8.0 (API level 26), this value remains constant
* > for the lifetime of the user's device. See the [ANDROID_ID](https://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID)
* > official docs for more information.
* @example
* `"dd96dec43fb81c97"`
* @platform android
*/
export function getAndroidId(): string {
if (Platform.OS !== 'android') {
throw new UnavailabilityError('expo-application', 'androidId');
}
return ExpoApplication.androidId;
}
// @needsAudit
/**
* Gets the referrer URL of the installed app with the [`Install Referrer API`](https://developer.android.com/google/play/installreferrer)
* from the Google Play Store. In practice, the referrer URL may not be a complete, absolute URL.
* @return A `Promise` that fulfills with a `string` of the referrer URL of the installed app.
*
* @example
* ```ts
* await Application.getInstallReferrerAsync();
* // "utm_source=google-play&utm_medium=organic"
* ```
* @platform android
*/
export async function getInstallReferrerAsync(): Promise<string> {
if (!ExpoApplication.getInstallReferrerAsync) {
throw new UnavailabilityError('expo-application', 'getInstallReferrerAsync');
}
return await ExpoApplication.getInstallReferrerAsync();
}
// @needsAudit
/**
* Gets the iOS "identifier for vendor" ([IDFV](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor))
* value, a string ID that uniquely identifies a device to the apps vendor. This method may
* sometimes return `nil`, in which case wait and call the method again later. This might happen
* when the device has been restarted before the user has unlocked the device.
*
* The OS will change the vendor identifier if all apps from the current app's vendor have been
* uninstalled.
*
* @return A `Promise` that fulfills with a `string` specifying the app's vendor ID. Apps from the
* same vendor will return the same ID. See Apple's documentation for more information about the
* vendor ID's semantics.
*
* @example
* ```ts
* await Application.getIosIdForVendorAsync();
* // "68753A44-4D6F-1226-9C60-0050E4C00067"
* ```
* @platform ios
*/
export async function getIosIdForVendorAsync(): Promise<string | null> {
if (!ExpoApplication.getIosIdForVendorAsync) {
throw new UnavailabilityError('expo-application', 'getIosIdForVendorAsync');
}
return await ExpoApplication.getIosIdForVendorAsync();
}
// @needsAudit
/**
* Gets the iOS application release type.
* @return Returns a promise which fulfills with an [`ApplicationReleaseType`](#applicationreleasetype).
* @platform ios
*/
export async function getIosApplicationReleaseTypeAsync(): Promise<ApplicationReleaseType> {
if (!ExpoApplication.getApplicationReleaseTypeAsync) {
throw new UnavailabilityError('expo-application', 'getApplicationReleaseTypeAsync');
}
return await ExpoApplication.getApplicationReleaseTypeAsync();
}
// @needsAudit
/**
* Gets the current [Apple Push Notification (APN)](https://developer.apple.com/documentation/bundleresources/entitlements/aps-environment?language=objc)
* service environment.
* @return Returns a promise fulfilled with the string, either `'development'` or `'production'`,
* based on the current APN environment, or `null` on the simulator as it does not support registering with APNs.
* @platform ios
*/
export async function getIosPushNotificationServiceEnvironmentAsync(): Promise<PushNotificationServiceEnvironment> {
if (!ExpoApplication.getPushNotificationServiceEnvironmentAsync) {
throw new UnavailabilityError('expo-application', 'getPushNotificationServiceEnvironmentAsync');
}
return await ExpoApplication.getPushNotificationServiceEnvironmentAsync();
}
// @needsAudit
/**
* Gets the time the app was installed onto the device, not counting subsequent updates. If the app
* is uninstalled and reinstalled, this method returns the time the app was reinstalled.
* - On iOS, this method uses the [`NSFileCreationDate`](https://developer.apple.com/documentation/foundation/nsfilecreationdate?language=objc)
* of the app's document root directory.
* - On Android, this method uses [`PackageInfo.firstInstallTime`](https://developer.android.com/reference/android/content/pm/PackageInfo.html#firstInstallTime).
* - On web, this method returns `null`.
*
* @return Returns a `Promise` that fulfills with a `Date` object that specifies the time the app
* was installed on the device.
*
* @example
* ```ts
* await Application.getInstallationTimeAsync();
* // 2019-07-18T18:08:26.121Z
* ```
*/
export async function getInstallationTimeAsync(): Promise<Date> {
if (!ExpoApplication.getInstallationTimeAsync) {
throw new UnavailabilityError('expo-application', 'getInstallationTimeAsync');
}
const installationTime = await ExpoApplication.getInstallationTimeAsync();
return new Date(installationTime);
}
// @needsAudit
/**
* Gets the last time the app was updated from the Google Play Store.
* @return Returns a `Promise` that fulfills with a `Date` object that specifies the last time
* the app was updated via the Google Play Store).
*
* @example
* ```ts
* await Application.getLastUpdateTimeAsync();
* // 2019-07-18T21:20:16.887Z
* ```
* @platform android
*/
export async function getLastUpdateTimeAsync(): Promise<Date> {
if (!ExpoApplication.getLastUpdateTimeAsync) {
throw new UnavailabilityError('expo-application', 'getLastUpdateTimeAsync');
}
const lastUpdateTime = await ExpoApplication.getLastUpdateTimeAsync();
return new Date(lastUpdateTime);
}
export { ApplicationReleaseType, PushNotificationServiceEnvironment };

View File

@@ -0,0 +1,14 @@
// @docsMissing
export enum ApplicationReleaseType {
UNKNOWN = 0,
SIMULATOR = 1,
ENTERPRISE = 2,
DEVELOPMENT = 3,
AD_HOC = 4,
APP_STORE = 5,
}
/**
* Maps to the [`aps-environment`](https://developer.apple.com/documentation/bundleresources/entitlements/aps-environment) key in the native target's registered entitlements.
*/
export type PushNotificationServiceEnvironment = 'development' | 'production' | null;

View File

@@ -0,0 +1,3 @@
import { requireNativeModule } from 'expo-modules-core';
export default requireNativeModule('ExpoApplication');

View File

@@ -0,0 +1,20 @@
export default {
get applicationName(): null {
return null;
},
get bundleId(): null {
return null;
},
get nativeApplicationVersion(): null {
return null;
},
get nativeBuildVersion(): null {
return null;
},
get androidId(): null {
return null;
},
async getInstallationTimeAsync(): Promise<null> {
return null;
},
};

View File

@@ -0,0 +1,9 @@
// @generated by expo-module-scripts
{
"extends": "expo-module-scripts/tsconfig.base",
"compilerOptions": {
"outDir": "./build"
},
"include": ["./src"],
"exclude": ["**/__mocks__/*", "**/__tests__/*"]
}