@symbiote-native/constants 3.0.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 A. Prokopenko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # @symbiote-native/constants
2
+
3
+ A wrapper package for [SymbioteNative](../../README.md) that makes
4
+ [`expo-constants`](https://github.com/expo/expo/tree/main/packages/expo-constants), trimmed to its
5
+ native fields, usable from **every** adapter: React, Vue, Svelte, Solid and Angular. Every field is
6
+ a plain value resolved once from the native module, so there is no hook, composable or service to
7
+ wrap: each adapter entry point re-exports the same `core`.
8
+
9
+ ## Install
10
+
11
+ **New app:**
12
+
13
+ ```bash
14
+ npx @symbiote-native/cli new my-app --constants
15
+ ```
16
+
17
+ **Existing SymbioteNative app:**
18
+
19
+ ```bash
20
+ npx @symbiote-native/cli add --constants
21
+ ```
22
+
23
+ Either way it installs `@symbiote-native/constants` and wires the native autolinking, see
24
+ [`@symbiote-native/cli`](../cli). `expo-constants` and `expo-modules-core` come along as pinned
25
+ dependencies: never install either yourself and never add the `expo` meta-package.
26
+
27
+ Autolinking is the same one-time `expo-modules-core` setup every Expo wrapper needs, see the
28
+ `symbiote-expo-native-module` project skill. On Android the package also registers
29
+ `ConstantsService`, the native provider the module reads its values from: without it the module
30
+ resolves but every field is empty.
31
+
32
+ ## Use it
33
+
34
+ ```ts
35
+ import { Constants, ExecutionEnvironment } from '@symbiote-native/constants';
36
+
37
+ Constants.sessionId; // string, new on every app launch
38
+ Constants.statusBarHeight; // number
39
+ Constants.systemFonts; // string[]
40
+ Constants.linkingUri; // string
41
+ Constants.executionEnvironment === ExecutionEnvironment.Bare; // boolean
42
+ await Constants.getWebViewUserAgentAsync(); // string | null
43
+ ```
44
+
45
+ `./react`, `./vue`, `./svelte` and `./solid` are `exports`-map aliases onto `src/core/`, and
46
+ `./angular` is a physical file only because Angular ships through a separate `ngc` build.
47
+
48
+ ## API
49
+
50
+ `Constants` (`IConstants`): `appOwnership`, `debugMode`, `deviceName`, `deviceYearClass`,
51
+ `executionEnvironment`, `experienceUrl`, `expoRuntimeVersion`, `expoVersion`, `isDetached`,
52
+ `intentUri`, `isHeadless`, `linkingUri`, `sessionId`, `statusBarHeight`, `systemFonts`,
53
+ `systemVersion`, `supportedExpoSdks`, `platform` (`ios` with `buildNumber`, `platform`, `model`,
54
+ `userInterfaceIdiom`, `systemVersion`; `android` with `versionCode`) and `getWebViewUserAgentAsync()`.
55
+
56
+ Plus the enums `AppOwnership`, `ExecutionEnvironment` and `UserInterfaceIdiom`, and
57
+ `createConstants(nativeModule)`, the function `Constants` is built with.
58
+
59
+ ## Not ported
60
+
61
+ - **The manifest family**: `manifest`, `manifest2`, `expoConfig`, `expoGoConfig` and `easConfig`.
62
+ Upstream reads them from an app manifest that `expo-cli`, EAS or `expo-updates` generate, and
63
+ this project has none. `createConstants` drops them even when the native module reports one.
64
+ - **`expo-updates` and dev-launcher manifest lookup**, for the same reason.
65
+ - **The web implementation** (`ExponentConstants.web.ts`) and the server entry, this project
66
+ targets iOS and Android only.
67
+
68
+ The upstream tests all cover the manifest and are not ported, except its linking URI check, which
69
+ has a counterpart in `constants.test.ts`.
70
+
71
+ Because the manifest is missing, this package does not unlock `expo-auth-session`'s `auth.expo.io`
72
+ proxy flow or the scheme auto-detection of `makeRedirectUri`: both read `Constants.expoConfig`.
73
+
74
+ ## Common questions
75
+
76
+ - **Where is `Constants.expoConfig`?** Not ported (no Expo manifest here); inline build-time values
77
+ through your own Babel or Metro config.
78
+ - **`Constants.manifest` is `null`.** Deprecated upstream and not available here.
79
+ - **Where is `installationId`?** Deprecated upstream; use `@symbiote-native/application`'s Android ID
80
+ or a stored id in `@symbiote-native/secure-store`.
81
+ - **`makeRedirectUri` needs a scheme.** Pass `scheme` explicitly.
82
+
83
+ Sources: [Expo docs: Constants](https://docs.expo.dev/versions/latest/sdk/constants/),
84
+ [expo/expo#44527](https://github.com/expo/expo/issues/44527).
85
+
86
+ ## Test it
87
+
88
+ Tests inject a fake native module in place of the real `requireNativeModule` resolution
89
+ (`src/core/constants.test.ts`, `vitest`), the same pattern as
90
+ [`@symbiote-native/application`](../application). Values on a real device are verified on-device.
@@ -0,0 +1 @@
1
+ export * from '../core';
@@ -0,0 +1,3 @@
1
+ // @symbiote-native/constants/angular: the Angular entry over the framework-agnostic core
2
+ // Nothing here is per-instance or event-driven, so there is no service to wrap, plain re-export
3
+ export * from '../core/index.js';
@@ -0,0 +1,5 @@
1
+ import type { INativeConstantsModule } from './native-module';
2
+ import type { IConstants } from './types';
3
+ /** The native fields of the `ExponentConstants` module, without the Expo manifest family */
4
+ export declare function createConstants(native: INativeConstantsModule): IConstants;
5
+ export declare const Constants: IConstants;
@@ -0,0 +1,19 @@
1
+ import { UnavailabilityError } from 'expo-modules-core';
2
+ import { expoConstants } from './native-module.js';
3
+ const NATIVE_MODULE_NAME = 'expo-constants';
4
+ /** The native fields of the `ExponentConstants` module, without the Expo manifest family */
5
+ export function createConstants(native) {
6
+ const { name, appOwnership, manifest, manifest2, expoConfig, expoGoConfig, easConfig, getWebViewUserAgentAsync, ...nativeFields } = native;
7
+ return {
8
+ ...nativeFields,
9
+ // Ensure this is null in bare workflow
10
+ appOwnership: appOwnership ?? null,
11
+ async getWebViewUserAgentAsync() {
12
+ if (!getWebViewUserAgentAsync) {
13
+ throw new UnavailabilityError(NATIVE_MODULE_NAME, 'getWebViewUserAgentAsync');
14
+ }
15
+ return getWebViewUserAgentAsync();
16
+ },
17
+ };
18
+ }
19
+ export const Constants = createConstants(expoConstants);
@@ -0,0 +1,2 @@
1
+ export { Constants, createConstants } from './constants';
2
+ export { AppOwnership, ExecutionEnvironment, UserInterfaceIdiom, type IAndroidPlatformConstants, type IConstants, type IIosPlatformConstants, type IPlatformConstants, } from './types';
@@ -0,0 +1,2 @@
1
+ export { Constants, createConstants } from './constants.js';
2
+ export { AppOwnership, ExecutionEnvironment, UserInterfaceIdiom, } from './types.js';
@@ -0,0 +1,12 @@
1
+ import type { AppOwnership, IConstants } from './types';
2
+ export type INativeConstantsModule = Omit<IConstants, 'appOwnership' | 'getWebViewUserAgentAsync'> & {
3
+ name?: string;
4
+ appOwnership?: AppOwnership | null;
5
+ manifest?: unknown;
6
+ manifest2?: unknown;
7
+ expoConfig?: unknown;
8
+ expoGoConfig?: unknown;
9
+ easConfig?: unknown;
10
+ getWebViewUserAgentAsync?: () => Promise<string | null>;
11
+ };
12
+ export declare const expoConstants: INativeConstantsModule;
@@ -0,0 +1,3 @@
1
+ import { requireNativeModule } from 'expo-modules-core';
2
+ const EXPONENT_CONSTANTS_MODULE_NAME = 'ExponentConstants';
3
+ export const expoConstants = requireNativeModule(EXPONENT_CONSTANTS_MODULE_NAME);
@@ -0,0 +1,52 @@
1
+ export declare enum AppOwnership {
2
+ Expo = "expo"
3
+ }
4
+ export declare enum ExecutionEnvironment {
5
+ Bare = "bare",
6
+ Standalone = "standalone",
7
+ StoreClient = "storeClient"
8
+ }
9
+ export declare enum UserInterfaceIdiom {
10
+ Handset = "handset",
11
+ Tablet = "tablet",
12
+ Desktop = "desktop",
13
+ TV = "tv",
14
+ Unsupported = "unsupported"
15
+ }
16
+ /** @platform ios */
17
+ export type IIosPlatformConstants = {
18
+ buildNumber: string | null;
19
+ platform: string;
20
+ model: string | null;
21
+ userInterfaceIdiom: UserInterfaceIdiom;
22
+ systemVersion: string;
23
+ };
24
+ /** @platform android */
25
+ export type IAndroidPlatformConstants = {
26
+ versionCode: number;
27
+ };
28
+ export type IPlatformConstants = {
29
+ ios?: IIosPlatformConstants;
30
+ android?: IAndroidPlatformConstants;
31
+ };
32
+ export type IConstants = {
33
+ appOwnership: AppOwnership | null;
34
+ debugMode: boolean;
35
+ deviceName?: string;
36
+ deviceYearClass: number | null;
37
+ executionEnvironment: ExecutionEnvironment;
38
+ experienceUrl: string;
39
+ expoRuntimeVersion: string | null;
40
+ expoVersion: string | null;
41
+ isDetached?: boolean;
42
+ intentUri?: string;
43
+ isHeadless: boolean;
44
+ linkingUri: string;
45
+ sessionId: string;
46
+ statusBarHeight: number;
47
+ systemFonts: string[];
48
+ systemVersion?: number;
49
+ supportedExpoSdks?: string[];
50
+ platform?: IPlatformConstants;
51
+ getWebViewUserAgentAsync: () => Promise<string | null>;
52
+ };
@@ -0,0 +1,18 @@
1
+ export var AppOwnership;
2
+ (function (AppOwnership) {
3
+ AppOwnership["Expo"] = "expo";
4
+ })(AppOwnership || (AppOwnership = {}));
5
+ export var ExecutionEnvironment;
6
+ (function (ExecutionEnvironment) {
7
+ ExecutionEnvironment["Bare"] = "bare";
8
+ ExecutionEnvironment["Standalone"] = "standalone";
9
+ ExecutionEnvironment["StoreClient"] = "storeClient";
10
+ })(ExecutionEnvironment || (ExecutionEnvironment = {}));
11
+ export var UserInterfaceIdiom;
12
+ (function (UserInterfaceIdiom) {
13
+ UserInterfaceIdiom["Handset"] = "handset";
14
+ UserInterfaceIdiom["Tablet"] = "tablet";
15
+ UserInterfaceIdiom["Desktop"] = "desktop";
16
+ UserInterfaceIdiom["TV"] = "tv";
17
+ UserInterfaceIdiom["Unsupported"] = "unsupported";
18
+ })(UserInterfaceIdiom || (UserInterfaceIdiom = {}));
@@ -0,0 +1 @@
1
+ export * from '../core';
@@ -0,0 +1,4 @@
1
+ // @symbiote-native/constants/angular: the Angular entry over the framework-agnostic core
2
+ // Nothing here is per-instance or event-driven, so there is no service to wrap, plain re-export
3
+ export * from '../core';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/angular/index.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,gGAAgG;AAChG,cAAc,SAAS,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { INativeConstantsModule } from './native-module';
2
+ import type { IConstants } from './types';
3
+ /** The native fields of the `ExponentConstants` module, without the Expo manifest family */
4
+ export declare function createConstants(native: INativeConstantsModule): IConstants;
5
+ export declare const Constants: IConstants;
@@ -0,0 +1,20 @@
1
+ import { UnavailabilityError } from 'expo-modules-core';
2
+ import { expoConstants } from './native-module';
3
+ const NATIVE_MODULE_NAME = 'expo-constants';
4
+ /** The native fields of the `ExponentConstants` module, without the Expo manifest family */
5
+ export function createConstants(native) {
6
+ const { name, appOwnership, manifest, manifest2, expoConfig, expoGoConfig, easConfig, getWebViewUserAgentAsync, ...nativeFields } = native;
7
+ return {
8
+ ...nativeFields,
9
+ // Ensure this is null in bare workflow
10
+ appOwnership: appOwnership ?? null,
11
+ async getWebViewUserAgentAsync() {
12
+ if (!getWebViewUserAgentAsync) {
13
+ throw new UnavailabilityError(NATIVE_MODULE_NAME, 'getWebViewUserAgentAsync');
14
+ }
15
+ return getWebViewUserAgentAsync();
16
+ },
17
+ };
18
+ }
19
+ export const Constants = createConstants(expoConstants);
20
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhD,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAE5C,4FAA4F;AAC5F,MAAM,UAAU,eAAe,CAAC,MAA8B;IAC5D,MAAM,EACJ,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,UAAU,EACV,YAAY,EACZ,SAAS,EACT,wBAAwB,EACxB,GAAG,YAAY,EAChB,GAAG,MAAM,CAAC;IAEX,OAAO;QACL,GAAG,YAAY;QACf,uCAAuC;QACvC,YAAY,EAAE,YAAY,IAAI,IAAI;QAClC,KAAK,CAAC,wBAAwB;YAC5B,IAAI,CAAC,wBAAwB,EAAE,CAAC;gBAC9B,MAAM,IAAI,mBAAmB,CAC3B,kBAAkB,EAClB,0BAA0B,CAC3B,CAAC;YACJ,CAAC;YACD,OAAO,wBAAwB,EAAE,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAe,eAAe,CAAC,aAAa,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { Constants, createConstants } from './constants';
2
+ export { AppOwnership, ExecutionEnvironment, UserInterfaceIdiom, type IAndroidPlatformConstants, type IConstants, type IIosPlatformConstants, type IPlatformConstants, } from './types';
@@ -0,0 +1,3 @@
1
+ export { Constants, createConstants } from './constants';
2
+ export { AppOwnership, ExecutionEnvironment, UserInterfaceIdiom, } from './types';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,GAKnB,MAAM,SAAS,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { AppOwnership, IConstants } from './types';
2
+ export type INativeConstantsModule = Omit<IConstants, 'appOwnership' | 'getWebViewUserAgentAsync'> & {
3
+ name?: string;
4
+ appOwnership?: AppOwnership | null;
5
+ manifest?: unknown;
6
+ manifest2?: unknown;
7
+ expoConfig?: unknown;
8
+ expoGoConfig?: unknown;
9
+ easConfig?: unknown;
10
+ getWebViewUserAgentAsync?: () => Promise<string | null>;
11
+ };
12
+ export declare const expoConstants: INativeConstantsModule;
@@ -0,0 +1,4 @@
1
+ import { requireNativeModule } from 'expo-modules-core';
2
+ const EXPONENT_CONSTANTS_MODULE_NAME = 'ExponentConstants';
3
+ export const expoConstants = requireNativeModule(EXPONENT_CONSTANTS_MODULE_NAME);
4
+ //# sourceMappingURL=native-module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-module.js","sourceRoot":"","sources":["../../src/core/native-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGxD,MAAM,8BAA8B,GAAG,mBAAmB,CAAC;AAkB3D,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAC9C,8BAA8B,CAC/B,CAAC"}
@@ -0,0 +1,52 @@
1
+ export declare enum AppOwnership {
2
+ Expo = "expo"
3
+ }
4
+ export declare enum ExecutionEnvironment {
5
+ Bare = "bare",
6
+ Standalone = "standalone",
7
+ StoreClient = "storeClient"
8
+ }
9
+ export declare enum UserInterfaceIdiom {
10
+ Handset = "handset",
11
+ Tablet = "tablet",
12
+ Desktop = "desktop",
13
+ TV = "tv",
14
+ Unsupported = "unsupported"
15
+ }
16
+ /** @platform ios */
17
+ export type IIosPlatformConstants = {
18
+ buildNumber: string | null;
19
+ platform: string;
20
+ model: string | null;
21
+ userInterfaceIdiom: UserInterfaceIdiom;
22
+ systemVersion: string;
23
+ };
24
+ /** @platform android */
25
+ export type IAndroidPlatformConstants = {
26
+ versionCode: number;
27
+ };
28
+ export type IPlatformConstants = {
29
+ ios?: IIosPlatformConstants;
30
+ android?: IAndroidPlatformConstants;
31
+ };
32
+ export type IConstants = {
33
+ appOwnership: AppOwnership | null;
34
+ debugMode: boolean;
35
+ deviceName?: string;
36
+ deviceYearClass: number | null;
37
+ executionEnvironment: ExecutionEnvironment;
38
+ experienceUrl: string;
39
+ expoRuntimeVersion: string | null;
40
+ expoVersion: string | null;
41
+ isDetached?: boolean;
42
+ intentUri?: string;
43
+ isHeadless: boolean;
44
+ linkingUri: string;
45
+ sessionId: string;
46
+ statusBarHeight: number;
47
+ systemFonts: string[];
48
+ systemVersion?: number;
49
+ supportedExpoSdks?: string[];
50
+ platform?: IPlatformConstants;
51
+ getWebViewUserAgentAsync: () => Promise<string | null>;
52
+ };
@@ -0,0 +1,19 @@
1
+ export var AppOwnership;
2
+ (function (AppOwnership) {
3
+ AppOwnership["Expo"] = "expo";
4
+ })(AppOwnership || (AppOwnership = {}));
5
+ export var ExecutionEnvironment;
6
+ (function (ExecutionEnvironment) {
7
+ ExecutionEnvironment["Bare"] = "bare";
8
+ ExecutionEnvironment["Standalone"] = "standalone";
9
+ ExecutionEnvironment["StoreClient"] = "storeClient";
10
+ })(ExecutionEnvironment || (ExecutionEnvironment = {}));
11
+ export var UserInterfaceIdiom;
12
+ (function (UserInterfaceIdiom) {
13
+ UserInterfaceIdiom["Handset"] = "handset";
14
+ UserInterfaceIdiom["Tablet"] = "tablet";
15
+ UserInterfaceIdiom["Desktop"] = "desktop";
16
+ UserInterfaceIdiom["TV"] = "tv";
17
+ UserInterfaceIdiom["Unsupported"] = "unsupported";
18
+ })(UserInterfaceIdiom || (UserInterfaceIdiom = {}));
19
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,YAEX;AAFD,WAAY,YAAY;IACtB,6BAAa,CAAA;AACf,CAAC,EAFW,YAAY,KAAZ,YAAY,QAEvB;AAED,MAAM,CAAN,IAAY,oBAIX;AAJD,WAAY,oBAAoB;IAC9B,qCAAa,CAAA;IACb,iDAAyB,CAAA;IACzB,mDAA2B,CAAA;AAC7B,CAAC,EAJW,oBAAoB,KAApB,oBAAoB,QAI/B;AAED,MAAM,CAAN,IAAY,kBAMX;AAND,WAAY,kBAAkB;IAC5B,yCAAmB,CAAA;IACnB,uCAAiB,CAAA;IACjB,yCAAmB,CAAA;IACnB,+BAAS,CAAA;IACT,iDAA2B,CAAA;AAC7B,CAAC,EANW,kBAAkB,KAAlB,kBAAkB,QAM7B"}
@@ -0,0 +1,19 @@
1
+ {
2
+ "android": {
3
+ "gradleProjectName": "expo-constants",
4
+ "modules": [
5
+ {
6
+ "importPath": "expo.modules.constants.ConstantsModule",
7
+ "className": "ConstantsModule",
8
+ "nativeName": "ExponentConstants"
9
+ }
10
+ ],
11
+ "services": [
12
+ {
13
+ "importPath": "expo.modules.constants.ConstantsService",
14
+ "className": "ConstantsService",
15
+ "gradleProjectName": "expo-constants"
16
+ }
17
+ ]
18
+ }
19
+ }
package/package.json ADDED
@@ -0,0 +1,150 @@
1
+ {
2
+ "name": "@symbiote-native/constants",
3
+ "version": "3.0.2",
4
+ "description": "expo-constants wrapped for SymbioteNative, trimmed to its native fields — one framework-agnostic core, built once and reachable from the React, Vue, Svelte, Solid, and Angular adapters. Session ID, status bar height, system fonts, linking URI, execution environment, device name and year class, the Android/iOS platform block and the WebView user agent. The Expo manifest (`expoConfig`, `manifest`, `easConfig`) is not ported.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/OneEyed1366/symbiote-native.git",
9
+ "directory": "packages/constants"
10
+ },
11
+ "homepage": "https://github.com/OneEyed1366/symbiote-native/tree/master/packages/constants#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/OneEyed1366/symbiote-native/issues"
14
+ },
15
+ "author": "Andrey Prokopenko <psevdoproger@gmail.com>",
16
+ "keywords": [
17
+ "react-native",
18
+ "symbiote-native",
19
+ "expo-constants",
20
+ "react",
21
+ "vue",
22
+ "svelte",
23
+ "solid",
24
+ "angular",
25
+ "session-id",
26
+ "status-bar-height"
27
+ ],
28
+ "type": "module",
29
+ "main": "./build/core/index.js",
30
+ "module": "./build/core/index.js",
31
+ "types": "./build/core/index.d.ts",
32
+ "exports": {
33
+ ".": {
34
+ "types": "./build/core/index.d.ts",
35
+ "default": "./build/core/index.js"
36
+ },
37
+ "./vue": {
38
+ "types": "./build/core/index.d.ts",
39
+ "default": "./build/core/index.js"
40
+ },
41
+ "./react": {
42
+ "types": "./build/core/index.d.ts",
43
+ "default": "./build/core/index.js"
44
+ },
45
+ "./svelte": {
46
+ "types": "./build/core/index.d.ts",
47
+ "default": "./build/core/index.js"
48
+ },
49
+ "./solid": {
50
+ "types": "./build/core/index.d.ts",
51
+ "default": "./build/core/index.js"
52
+ },
53
+ "./angular": {
54
+ "types": "./build-ngc/angular/index.d.ts",
55
+ "react-native": "./build-ngc/angular/index.js",
56
+ "default": "./src/angular/index.ts"
57
+ }
58
+ },
59
+ "files": [
60
+ "src",
61
+ "build",
62
+ "build-ngc",
63
+ "native-link.json",
64
+ "!src/**/*.test.*",
65
+ "!src/**/*.spec.*",
66
+ "!src/**/*.detox.*"
67
+ ],
68
+ "publishConfig": {
69
+ "access": "public"
70
+ },
71
+ "dependencies": {
72
+ "expo-constants": "57.0.19",
73
+ "expo-modules-core": "57.0.20"
74
+ },
75
+ "peerDependencies": {
76
+ "@angular/core": ">=20",
77
+ "@vue/runtime-core": "^3.5.13",
78
+ "react": ">=19.0.0",
79
+ "react-native": ">=0.86",
80
+ "solid-js": ">=1.9.0",
81
+ "svelte": ">=5.56.0",
82
+ "vue": ">=3.5.0",
83
+ "@symbiote-native/angular": "^3.1.3",
84
+ "@symbiote-native/engine": "^1.4.0",
85
+ "@symbiote-native/react": "^3.1.0",
86
+ "@symbiote-native/svelte": "^3.0.5",
87
+ "@symbiote-native/solid": "^3.0.5",
88
+ "@symbiote-native/vue": "^3.1.0"
89
+ },
90
+ "peerDependenciesMeta": {
91
+ "@symbiote-native/angular": {
92
+ "optional": true
93
+ },
94
+ "@symbiote-native/react": {
95
+ "optional": true
96
+ },
97
+ "@symbiote-native/solid": {
98
+ "optional": true
99
+ },
100
+ "@symbiote-native/svelte": {
101
+ "optional": true
102
+ },
103
+ "@symbiote-native/vue": {
104
+ "optional": true
105
+ },
106
+ "@angular/core": {
107
+ "optional": true
108
+ },
109
+ "@vue/runtime-core": {
110
+ "optional": true
111
+ },
112
+ "react": {
113
+ "optional": true
114
+ },
115
+ "solid-js": {
116
+ "optional": true
117
+ },
118
+ "svelte": {
119
+ "optional": true
120
+ },
121
+ "vue": {
122
+ "optional": true
123
+ }
124
+ },
125
+ "devDependencies": {
126
+ "@angular/compiler": "~22.0.8",
127
+ "@angular/compiler-cli": "~22.0.8",
128
+ "@angular/core": "~22.0.8",
129
+ "@types/node": "^26.0.0",
130
+ "@types/react": "^19.2.0",
131
+ "@vue/runtime-core": "^3.5.13",
132
+ "react": "19.2.3",
133
+ "solid-js": "^1.9.14",
134
+ "svelte": "^5.56.0",
135
+ "typescript": "~6.0.0",
136
+ "@symbiote-native/angular": "3.1.3",
137
+ "@symbiote-native/engine": "1.4.0",
138
+ "@symbiote-native/react": "3.1.0",
139
+ "@symbiote-native/svelte": "3.0.5",
140
+ "@symbiote-native/vue": "3.1.0",
141
+ "@symbiote-native/test-utils": "0.4.5",
142
+ "@symbiote-native/solid": "3.0.5"
143
+ },
144
+ "scripts": {
145
+ "typecheck": "tsc --build",
146
+ "clean": "rm -rf build-ngc",
147
+ "ng:build": "pnpm run clean && ngc -p tsconfig.angular.json",
148
+ "format": "prettier --write \"src/**/*.{ts,tsx}\""
149
+ }
150
+ }
@@ -0,0 +1,3 @@
1
+ // @symbiote-native/constants/angular: the Angular entry over the framework-agnostic core
2
+ // Nothing here is per-instance or event-driven, so there is no service to wrap, plain re-export
3
+ export * from '../core';
@@ -0,0 +1,38 @@
1
+ import { UnavailabilityError } from 'expo-modules-core';
2
+ import { expoConstants } from './native-module';
3
+ import type { INativeConstantsModule } from './native-module';
4
+ import type { IConstants } from './types';
5
+
6
+ const NATIVE_MODULE_NAME = 'expo-constants';
7
+
8
+ /** The native fields of the `ExponentConstants` module, without the Expo manifest family */
9
+ export function createConstants(native: INativeConstantsModule): IConstants {
10
+ const {
11
+ name,
12
+ appOwnership,
13
+ manifest,
14
+ manifest2,
15
+ expoConfig,
16
+ expoGoConfig,
17
+ easConfig,
18
+ getWebViewUserAgentAsync,
19
+ ...nativeFields
20
+ } = native;
21
+
22
+ return {
23
+ ...nativeFields,
24
+ // Ensure this is null in bare workflow
25
+ appOwnership: appOwnership ?? null,
26
+ async getWebViewUserAgentAsync() {
27
+ if (!getWebViewUserAgentAsync) {
28
+ throw new UnavailabilityError(
29
+ NATIVE_MODULE_NAME,
30
+ 'getWebViewUserAgentAsync',
31
+ );
32
+ }
33
+ return getWebViewUserAgentAsync();
34
+ },
35
+ };
36
+ }
37
+
38
+ export const Constants: IConstants = createConstants(expoConstants);
@@ -0,0 +1,10 @@
1
+ export { Constants, createConstants } from './constants';
2
+ export {
3
+ AppOwnership,
4
+ ExecutionEnvironment,
5
+ UserInterfaceIdiom,
6
+ type IAndroidPlatformConstants,
7
+ type IConstants,
8
+ type IIosPlatformConstants,
9
+ type IPlatformConstants,
10
+ } from './types';
@@ -0,0 +1,24 @@
1
+ import { requireNativeModule } from 'expo-modules-core';
2
+ import type { AppOwnership, IConstants } from './types';
3
+
4
+ const EXPONENT_CONSTANTS_MODULE_NAME = 'ExponentConstants';
5
+
6
+ // The module object itself carries the constants as properties. Its manifest family is typed
7
+ // `unknown` because it is read only to be dropped
8
+ export type INativeConstantsModule = Omit<
9
+ IConstants,
10
+ 'appOwnership' | 'getWebViewUserAgentAsync'
11
+ > & {
12
+ name?: string;
13
+ appOwnership?: AppOwnership | null;
14
+ manifest?: unknown;
15
+ manifest2?: unknown;
16
+ expoConfig?: unknown;
17
+ expoGoConfig?: unknown;
18
+ easConfig?: unknown;
19
+ getWebViewUserAgentAsync?: () => Promise<string | null>;
20
+ };
21
+
22
+ export const expoConstants = requireNativeModule<INativeConstantsModule>(
23
+ EXPONENT_CONSTANTS_MODULE_NAME,
24
+ );
@@ -0,0 +1,60 @@
1
+ export enum AppOwnership {
2
+ Expo = 'expo',
3
+ }
4
+
5
+ export enum ExecutionEnvironment {
6
+ Bare = 'bare',
7
+ Standalone = 'standalone',
8
+ StoreClient = 'storeClient',
9
+ }
10
+
11
+ export enum UserInterfaceIdiom {
12
+ Handset = 'handset',
13
+ Tablet = 'tablet',
14
+ Desktop = 'desktop',
15
+ TV = 'tv',
16
+ Unsupported = 'unsupported',
17
+ }
18
+
19
+ /** @platform ios */
20
+ export type IIosPlatformConstants = {
21
+ buildNumber: string | null;
22
+ platform: string;
23
+ model: string | null;
24
+ userInterfaceIdiom: UserInterfaceIdiom;
25
+ systemVersion: string;
26
+ };
27
+
28
+ /** @platform android */
29
+ export type IAndroidPlatformConstants = {
30
+ versionCode: number;
31
+ };
32
+
33
+ export type IPlatformConstants = {
34
+ ios?: IIosPlatformConstants;
35
+ android?: IAndroidPlatformConstants;
36
+ };
37
+
38
+ // The native fields of upstream's `Constants`. The manifest family (`manifest`, `manifest2`,
39
+ // `expoConfig`, `expoGoConfig`, `easConfig`) is not ported, this project has no Expo manifest
40
+ export type IConstants = {
41
+ appOwnership: AppOwnership | null;
42
+ debugMode: boolean;
43
+ deviceName?: string;
44
+ deviceYearClass: number | null;
45
+ executionEnvironment: ExecutionEnvironment;
46
+ experienceUrl: string;
47
+ expoRuntimeVersion: string | null;
48
+ expoVersion: string | null;
49
+ isDetached?: boolean;
50
+ intentUri?: string;
51
+ isHeadless: boolean;
52
+ linkingUri: string;
53
+ sessionId: string;
54
+ statusBarHeight: number;
55
+ systemFonts: string[];
56
+ systemVersion?: number;
57
+ supportedExpoSdks?: string[];
58
+ platform?: IPlatformConstants;
59
+ getWebViewUserAgentAsync: () => Promise<string | null>;
60
+ };