@apirtc/expo-apirtc-options-plugin 0.0.7 → 0.0.9

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 Apizee
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 CHANGED
@@ -36,6 +36,7 @@ Declare the plugin in your `app.json`:
36
36
  | `enableMediaProjectionService` | Enable screen sharing on Android (MediaProjection service) | `true` |
37
37
  | `enableVideoEffects` | Enable background blur and background image replacement on Android | `true` |
38
38
  | `appleTeamId` | Apple Team ID used for the iOS broadcast extension | `"APPLE_TEAM_ID_NOT_SET"` |
39
+ | `logLevel` | Plugin log verbosity: `"silent"`, `"error"`, `"warn"`, `"info"`, `"debug"` | `"warn"` |
39
40
 
40
41
  ## What does this plugin do?
41
42
 
@@ -94,3 +95,9 @@ if (Platform.OS === 'android') {
94
95
  - ML Kit Selfie Segmentation (`16.0.0-beta6`) is currently in beta — there is no GA release of this library.
95
96
  - Background effects are applied via WebRTC's `VideoProcessor` API, so both the local preview and remote peers see the processed video.
96
97
  - For persistence across sessions, save the selected effect ID with `AsyncStorage` and re-apply it after `createStreamFromUserMedia()`.
98
+
99
+ ## Contributing
100
+
101
+ Contributions are welcome! Feel free to open an issue or submit a pull request on GitHub.
102
+
103
+ This plugin is maintained by [Apizee](https://www.apizee.com).
@@ -0,0 +1,9 @@
1
+ export type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug';
2
+ export declare function setLogLevel(level: LogLevel): void;
3
+ export declare function getLogLevel(): LogLevel;
4
+ export declare const logger: {
5
+ error(...args: any[]): void;
6
+ warn(...args: any[]): void;
7
+ info(...args: any[]): void;
8
+ debug(...args: any[]): void;
9
+ };
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logger = void 0;
4
+ exports.setLogLevel = setLogLevel;
5
+ exports.getLogLevel = getLogLevel;
6
+ const LOG_LEVELS = {
7
+ silent: 0,
8
+ error: 1,
9
+ warn: 2,
10
+ info: 3,
11
+ debug: 4,
12
+ };
13
+ let currentLevel = 'warn';
14
+ function setLogLevel(level) {
15
+ currentLevel = level;
16
+ }
17
+ function getLogLevel() {
18
+ return currentLevel;
19
+ }
20
+ function shouldLog(level) {
21
+ return LOG_LEVELS[level] <= LOG_LEVELS[currentLevel];
22
+ }
23
+ exports.logger = {
24
+ error(...args) {
25
+ if (shouldLog('error'))
26
+ console.error('[expo-apirtc]', ...args);
27
+ },
28
+ warn(...args) {
29
+ if (shouldLog('warn'))
30
+ console.warn('[expo-apirtc]', ...args);
31
+ },
32
+ info(...args) {
33
+ if (shouldLog('info'))
34
+ console.log('[expo-apirtc]', ...args);
35
+ },
36
+ debug(...args) {
37
+ if (shouldLog('debug'))
38
+ console.log('[expo-apirtc][DEBUG]', ...args);
39
+ },
40
+ };
@@ -11,4 +11,5 @@
11
11
 
12
12
  @interface RCT_EXTERN_MODULE(ReactNativeApiRTC_RPK, RCTEventEmitter)
13
13
  RCT_EXTERN_METHOD(sendBroadcastNeedToBeStopped)
14
+ RCT_EXTERN_METHOD(showVideoEffectsUI)
14
15
  @end
@@ -9,6 +9,7 @@ import Foundation
9
9
  import ReplayKit
10
10
  import Photos
11
11
  import UIKit
12
+ import AVFoundation
12
13
  import React
13
14
 
14
15
  @objc(ReactNativeApiRTC_RPK)
@@ -63,6 +64,15 @@ class ReactNativeApiRTC_RPK: RCTEventEmitter {
63
64
  status = "Empty"
64
65
  }
65
66
 
67
+ @objc
68
+ func showVideoEffectsUI() {
69
+ if #available(iOS 15.4, *) {
70
+ DispatchQueue.main.async {
71
+ AVCaptureDevice.showSystemUserInterface(.videoEffects)
72
+ }
73
+ }
74
+ }
75
+
66
76
  //This function is used to send a notification to the extension to stop the broadcast
67
77
  @objc
68
78
  func sendBroadcastNeedToBeStopped() {
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const config_plugins_1 = require("@expo/config-plugins");
37
37
  const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
+ const logger_1 = require("./logger");
39
40
  const REQUIRED_PERMISSIONS = [
40
41
  "android.permission.ACCESS_NETWORK_STATE",
41
42
  "android.permission.CAMERA",
@@ -62,7 +63,26 @@ function getAndroidPackagePath(projectRoot) {
62
63
  packageName = match[1];
63
64
  }
64
65
  }
65
- // Fallback: lire dans app.json
66
+ // Fallback: read from app.config.ts or app.config.js
67
+ if (!packageName) {
68
+ const configFiles = ['app.config.ts', 'app.config.js'];
69
+ for (const configFile of configFiles) {
70
+ const configPath = path.join(projectRoot, configFile);
71
+ if (fs.existsSync(configPath)) {
72
+ const configContent = fs.readFileSync(configPath, 'utf8');
73
+ // Match android.package in various forms:
74
+ // - package: "com.example.app"
75
+ // - package: 'com.example.app'
76
+ // - "package": "com.example.app"
77
+ const match = configContent.match(/["']?package["']?\s*[:=]\s*["']([\w.]+)["']/);
78
+ if (match) {
79
+ packageName = match[1];
80
+ break;
81
+ }
82
+ }
83
+ }
84
+ }
85
+ // Fallback: read from app.json
66
86
  if (!packageName) {
67
87
  const appJsonPath = path.join(projectRoot, 'app.json');
68
88
  if (fs.existsSync(appJsonPath)) {
@@ -71,7 +91,7 @@ function getAndroidPackagePath(projectRoot) {
71
91
  }
72
92
  }
73
93
  if (!packageName) {
74
- throw new Error('Package name not found in AndroidManifest.xml or app.json');
94
+ throw new Error('Package name not found in AndroidManifest.xml, app.config.ts, app.config.js or app.json');
75
95
  }
76
96
  return path.join(projectRoot, 'android/app/src/main/java', ...packageName.split('.'));
77
97
  }
@@ -98,7 +118,7 @@ function copyAndPatchJavaFiles(projectRoot) {
98
118
  let content = fs.readFileSync(src, 'utf8');
99
119
  content = content.replace(/^package\s+[\w.]+;/m, `package ${packageName};`);
100
120
  fs.writeFileSync(dest, content, 'utf8');
101
- console.log(`Copied and patched ${file} to android sources with package: ${packageName}`);
121
+ logger_1.logger.info(`Copied and patched ${file} to android sources with package: ${packageName}`);
102
122
  }
103
123
  });
104
124
  }
@@ -126,10 +146,10 @@ function copyAndPatchKotlinFiles(projectRoot) {
126
146
  // Kotlin package declaration has no trailing semicolon
127
147
  content = content.replace(/^package\s+[\w.]+/m, `package ${packageName}`);
128
148
  fs.writeFileSync(dest, content, 'utf8');
129
- console.log(`Copied and patched ${file} to android sources with package: ${packageName}`);
149
+ logger_1.logger.info(`Copied and patched ${file} to android sources with package: ${packageName}`);
130
150
  }
131
151
  else {
132
- console.warn(`Kotlin source not found: ${src}`);
152
+ logger_1.logger.warn(`Kotlin source not found: ${src}`);
133
153
  }
134
154
  });
135
155
  }
@@ -140,13 +160,13 @@ const withAndroidPermissions = (config) => {
140
160
  manifest['uses-permission'] = [];
141
161
  }
142
162
  REQUIRED_PERMISSIONS.forEach((permission) => {
143
- console.error('check manifest permission:', permission);
163
+ logger_1.logger.debug('check manifest permission:', permission);
144
164
  if (Array.isArray(manifest['uses-permission']) &&
145
165
  !manifest['uses-permission'].some((item) => item.$ && item.$['android:name'] === permission)) {
146
166
  manifest['uses-permission'].push({
147
167
  $: { 'android:name': permission }
148
168
  });
149
- console.error(`Added permission: ${permission}`);
169
+ logger_1.logger.info(`Added permission: ${permission}`);
150
170
  }
151
171
  });
152
172
  return config;
@@ -156,33 +176,15 @@ const withMlKitGradleDep = (config) => {
156
176
  return (0, config_plugins_1.withAppBuildGradle)(config, (config) => {
157
177
  if (!config.modResults.contents.includes('segmentation-selfie')) {
158
178
  config.modResults.contents = config.modResults.contents.replace(/(\s*dependencies\s*\{)/, `$1\n ${MLKIT_SEGMENTATION_DEP}`);
159
- console.log('Added ML Kit segmentation-selfie dependency to app/build.gradle');
179
+ logger_1.logger.info('Added ML Kit segmentation-selfie dependency to app/build.gradle');
160
180
  }
161
181
  return config;
162
182
  });
163
183
  };
164
184
  const withAndroidPlugin = (config, props) => {
165
- console.error('withAndroidPlugin called with props:', props);
185
+ logger_1.logger.info('withAndroidPlugin called with props:', props);
166
186
  let updatedConfig = (0, config_plugins_1.withMainApplication)(config, (config) => {
167
187
  const mainApplication = config.modResults;
168
- if (props.enableMediaProjectionService === false) {
169
- console.warn('Media Projection Service is disabled, skipping modifications.');
170
- return config;
171
- }
172
- // Add WebRTCModuleOptions import
173
- if (!mainApplication.contents.includes('import com.oney.WebRTCModule.WebRTCModuleOptions')) {
174
- mainApplication.contents = mainApplication.contents.replace(/(package\s+[\w.]+(?:\r?\n))/, `$1\nimport com.oney.WebRTCModule.WebRTCModuleOptions\n`);
175
- }
176
- // Add WebRTCModuleOptions code at start of onCreate()
177
- const onCreateRegex = /override fun onCreate\(\) \{\n/;
178
- const customCode = [
179
- ' val options: WebRTCModuleOptions = WebRTCModuleOptions.getInstance()',
180
- ' options.enableMediaProjectionService = true\n'
181
- ].join('\n');
182
- if (!mainApplication.contents.includes('WebRTCModuleOptions.getInstance()')) {
183
- mainApplication.contents = mainApplication.contents.replace(onCreateRegex, match => `${match}${customCode}`);
184
- }
185
- // Add AppLifecyclePackage import and registration
186
188
  const packageName = (() => {
187
189
  try {
188
190
  return getPackageName(config.modRequest.projectRoot);
@@ -191,6 +193,26 @@ const withAndroidPlugin = (config, props) => {
191
193
  return null;
192
194
  }
193
195
  })();
196
+ // Add WebRTCModuleOptions (Media Projection Service) if enabled
197
+ if (props.enableMediaProjectionService !== false) {
198
+ // Add WebRTCModuleOptions import
199
+ if (!mainApplication.contents.includes('import com.oney.WebRTCModule.WebRTCModuleOptions')) {
200
+ mainApplication.contents = mainApplication.contents.replace(/(package\s+[\w.]+(?:\r?\n))/, `$1\nimport com.oney.WebRTCModule.WebRTCModuleOptions\n`);
201
+ }
202
+ // Add WebRTCModuleOptions code at start of onCreate()
203
+ const onCreateRegex = /override fun onCreate\(\) \{\n/;
204
+ const customCode = [
205
+ ' val options: WebRTCModuleOptions = WebRTCModuleOptions.getInstance()',
206
+ ' options.enableMediaProjectionService = true\n'
207
+ ].join('\n');
208
+ if (!mainApplication.contents.includes('WebRTCModuleOptions.getInstance()')) {
209
+ mainApplication.contents = mainApplication.contents.replace(onCreateRegex, match => `${match}${customCode}`);
210
+ }
211
+ }
212
+ else {
213
+ logger_1.logger.info('Media Projection Service is disabled, skipping WebRTCModuleOptions modifications.');
214
+ }
215
+ // Add AppLifecyclePackage import and registration
194
216
  if (packageName) {
195
217
  const importLine = `import ${packageName}.AppLifecyclePackage\n`;
196
218
  if (!mainApplication.contents.includes(importLine.trim())) {
@@ -223,6 +245,26 @@ const withAndroidPlugin = (config, props) => {
223
245
  updatedConfig = withMlKitGradleDep(updatedConfig);
224
246
  }
225
247
  updatedConfig = withAndroidPermissions(updatedConfig);
248
+ // Fix NullPointerException in ReactActivityDelegate.onUserLeaveHint
249
+ // This crash occurs when Media Projection permission dialog pauses the activity
250
+ updatedConfig = (0, config_plugins_1.withMainActivity)(updatedConfig, (config) => {
251
+ const mainActivity = config.modResults;
252
+ if (!mainActivity.contents.includes('onUserLeaveHint')) {
253
+ // Add the override before the closing brace of the class
254
+ const onUserLeaveHintCode = `
255
+ override fun onUserLeaveHint() {
256
+ try {
257
+ super.onUserLeaveHint()
258
+ } catch (e: NullPointerException) {
259
+ // Workaround for NPE in ReactActivityDelegate.onUserLeaveHint
260
+ // when Media Projection permission dialog pauses the activity
261
+ }
262
+ }
263
+ `;
264
+ mainActivity.contents = mainActivity.contents.replace(/\n}\s*$/, `${onUserLeaveHintCode}\n}`);
265
+ }
266
+ return config;
267
+ });
226
268
  return updatedConfig;
227
269
  };
228
270
  exports.default = withAndroidPlugin;
@@ -41,16 +41,17 @@ const plist_1 = __importDefault(require("@expo/plist"));
41
41
  const fs = __importStar(require("fs"));
42
42
  const path = __importStar(require("path"));
43
43
  const util = __importStar(require("util"));
44
+ const logger_1 = require("./logger");
44
45
  const quoted = (str) => {
45
46
  return util.format(`"%s"`, str);
46
47
  };
47
48
  const withIosBroadcastExtension = (config, props) => {
48
- console.log('withIosBroadcastExtension called with props:', props);
49
+ logger_1.logger.info('withIosBroadcastExtension called with props:', props);
49
50
  config = withAppEntitlements(config);
50
51
  config = withInfoPlistRTC(config);
51
52
  config = withBroadcastExtensionXcodeTarget(config, props);
52
53
  config = withBroadcastExtensionPlist(config);
53
- //TODO Suite à relire
54
+ //TODO Review this section
54
55
  return config;
55
56
  };
56
57
  const withAppEntitlements = (config) => {
@@ -126,7 +127,7 @@ const withBroadcastExtensionXcodeTarget = (config, props) => {
126
127
  const addBroadcastExtensionXcodeTarget = (proj, { appName, extensionName, extensionBundleIdentifier, currentProjectVersion, marketingVersion, appleTeamId, }) => {
127
128
  var _a;
128
129
  if (((_a = proj.getFirstProject().firstProject.targets) === null || _a === void 0 ? void 0 : _a.length) > 1) {
129
- console.error("addBroadcastExtensionXcodeTarget targets?.length > 1");
130
+ logger_1.logger.error("addBroadcastExtensionXcodeTarget targets?.length > 1");
130
131
  return;
131
132
  }
132
133
  const targetUuid = proj.generateUuid();
@@ -172,7 +173,7 @@ const addXCConfigurationList = (proj, { extensionBundleIdentifier, currentProjec
172
173
  CLANG_WARN_DOCUMENTATION_COMMENTS: 'YES',
173
174
  CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER: 'YES',
174
175
  CLANG_WARN_UNGUARDED_AVAILABILITY: 'YES_AGGRESSIVE',
175
- DEVELOPMENT_TEAM: appleTeamId ? quoted(appleTeamId) : undefined, // <-- Ajoute ici
176
+ DEVELOPMENT_TEAM: appleTeamId ? quoted(appleTeamId) : undefined,
176
177
  CODE_SIGN_ENTITLEMENTS: `${appName}/${appName}.entitlements`,
177
178
  CODE_SIGN_STYLE: 'Automatic',
178
179
  CURRENT_PROJECT_VERSION: currentProjectVersion,
@@ -350,11 +351,11 @@ const addSourceFiles = (proj, extensionRootPath) => {
350
351
  const targetUuid = proj.findTargetKey('screenSharing_Extension');
351
352
  const groupUuid = proj.findPBXGroupKey({ name: 'screenSharing_Extension' });
352
353
  if (!targetUuid) {
353
- console.error(`Failed to find "screenSharing_Extension" target!`);
354
+ logger_1.logger.error(`Failed to find "screenSharing_Extension" target!`);
354
355
  return;
355
356
  }
356
357
  if (!groupUuid) {
357
- console.error(`Failed to find "screenSharing_Extension" group!`);
358
+ logger_1.logger.error(`Failed to find "screenSharing_Extension" group!`);
358
359
  return;
359
360
  }
360
361
  proj.addSourceFile('Atomic.swift', {
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const config_plugins_1 = require("@expo/config-plugins");
37
37
  const path = __importStar(require("path"));
38
38
  const fs = __importStar(require("fs"));
39
+ const logger_1 = require("./logger");
39
40
  const NATIVE_FILES = [
40
41
  'ReactNativeApiRTC_RPK.swift',
41
42
  'ReactNativeApiRTC_RPK.m',
@@ -53,11 +54,11 @@ function copyNativeFiles(projectRoot, iosProjectName) {
53
54
  const src = path.join(nativeSrcPath, file);
54
55
  const dest = path.join(iosPath, file);
55
56
  if (!fs.existsSync(src)) {
56
- console.warn(`⚠️ Fichier manquant : ${src}`);
57
+ logger_1.logger.warn(`File not found: ${src}`);
57
58
  continue;
58
59
  }
59
60
  fs.copyFileSync(src, dest);
60
- console.log(`📄 Copié : ${file}`);
61
+ logger_1.logger.info(`Copied: ${file}`);
61
62
  }
62
63
  }
63
64
  function copyBridgingFiles(projectRoot, iosProjectName) {
@@ -67,11 +68,11 @@ function copyBridgingFiles(projectRoot, iosProjectName) {
67
68
  const src = path.join(nativeSrcPath, file);
68
69
  const dest = path.join(iosPath, file);
69
70
  if (!fs.existsSync(src)) {
70
- console.warn(`⚠️ Fichier manquant : ${src}`);
71
+ logger_1.logger.warn(`File not found: ${src}`);
71
72
  continue;
72
73
  }
73
74
  fs.copyFileSync(src, dest);
74
- console.log(`📄 Copié : ${file}`);
75
+ logger_1.logger.info(`Copied: ${file}`);
75
76
  }
76
77
  }
77
78
  const withNativeFilesPlugin = (config) => {
@@ -83,30 +84,30 @@ const withNativeFilesPlugin = (config) => {
83
84
  const nativeGroup = project.getFirstProject().firstProject.mainGroup;
84
85
  copyNativeFiles(projectRoot, iosProjectName);
85
86
  copyBridgingFiles(projectRoot, iosProjectName);
86
- // Trouve la section Sources (PBXSourcesBuildPhase)
87
+ // Find the Sources section (PBXSourcesBuildPhase)
87
88
  const buildPhases = project.hash.project.objects['PBXSourcesBuildPhase'];
88
89
  const buildPhaseEntry = Object.entries(buildPhases).find(([key, val]) => key !== 'isa' && (val === null || val === void 0 ? void 0 : val.isa) === 'PBXSourcesBuildPhase');
89
90
  if (!buildPhaseEntry) {
90
- throw new Error('PBXSourcesBuildPhase non trouvé dans le projet Xcode.');
91
+ throw new Error('PBXSourcesBuildPhase not found in Xcode project.');
91
92
  }
92
93
  const [sourcesBuildPhaseUuid, sourcesBuildPhase] = buildPhaseEntry;
93
94
  sourcesBuildPhase.files = sourcesBuildPhase.files || [];
94
95
  for (const fileName of NATIVE_FILES) {
95
96
  const filePath = path.join(iosDir, iosProjectName, fileName);
96
97
  if (!fs.existsSync(filePath)) {
97
- console.warn(`⚠️ Fichier natif introuvable : ${filePath}`);
98
+ logger_1.logger.warn(`Native file not found: ${filePath}`);
98
99
  continue;
99
100
  }
100
101
  const file = project.addFile(path.join(iosProjectName, fileName), nativeGroup);
101
102
  if (!(file === null || file === void 0 ? void 0 : file.fileRef)) {
102
- console.warn(`❌ Échec de l'ajout de : ${fileName}`);
103
+ logger_1.logger.warn(`Failed to add: ${fileName}`);
103
104
  continue;
104
105
  }
105
- // Vérifie s’il est déjà présent
106
+ // Check if already present
106
107
  const alreadyExists = sourcesBuildPhase.files.some((f) => (f === null || f === void 0 ? void 0 : f.comment) === `${fileName} in Sources`);
107
108
  if (alreadyExists)
108
109
  continue;
109
- // Crée un buildFile
110
+ // Create a buildFile
110
111
  const buildFileUuid = project.generateUuid();
111
112
  project.hash.project.objects['PBXBuildFile'][buildFileUuid] = {
112
113
  isa: 'PBXBuildFile',
@@ -117,7 +118,7 @@ const withNativeFilesPlugin = (config) => {
117
118
  value: buildFileUuid,
118
119
  comment: `${fileName} in Sources`,
119
120
  });
120
- console.log(`✅ Fichier ajouté : ${fileName}`);
121
+ logger_1.logger.info(`File added: ${fileName}`);
121
122
  }
122
123
  // Swift config
123
124
  const targetUuid = project.getFirstTarget().uuid;
@@ -1,8 +1,10 @@
1
1
  import { ConfigPlugin } from '@expo/config-plugins';
2
+ import { LogLevel } from './logger';
2
3
  type PluginProps = {
3
4
  enableMediaProjectionService?: boolean;
4
5
  enableVideoEffects?: boolean;
5
6
  appleTeamId?: string;
7
+ logLevel?: LogLevel;
6
8
  };
7
9
  export declare const withPlugin: ConfigPlugin<PluginProps>;
8
10
  export default withPlugin;
@@ -7,11 +7,15 @@ exports.withPlugin = void 0;
7
7
  const withAndroidPlugin_1 = __importDefault(require("./withAndroidPlugin"));
8
8
  const withIosBroadcastExtension_1 = __importDefault(require("./withIosBroadcastExtension"));
9
9
  const withIosRPKFiles_1 = __importDefault(require("./withIosRPKFiles"));
10
+ const logger_1 = require("./logger");
10
11
  const withPlugin = (config, props = {
11
12
  enableMediaProjectionService: true,
12
13
  enableVideoEffects: true,
13
14
  appleTeamId: process.env.EXPO_APPLE_TEAM_ID || 'APPLE_TEAM_ID_NOT_SET',
14
15
  }) => {
16
+ if (props.logLevel) {
17
+ (0, logger_1.setLogLevel)(props.logLevel);
18
+ }
15
19
  config = (0, withAndroidPlugin_1.default)(config, props);
16
20
  config = (0, withIosBroadcastExtension_1.default)(config, props);
17
21
  config = (0, withIosRPKFiles_1.default)(config, props);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@apirtc/expo-apirtc-options-plugin",
3
- "version": "0.0.7",
4
- "description": "Plugin Expo pour ajouter les features apiRTC dans une application React Native",
3
+ "version": "0.0.9",
4
+ "description": "Expo Plugin to add apiRTC features in a React Native application",
5
5
  "main": "index.js",
6
6
  "keywords": [
7
7
  "expo",
@@ -12,6 +12,11 @@
12
12
  ],
13
13
  "author": "F.Luart",
14
14
  "license": "MIT",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/ApiRTC/expo-apirtc-options-plugin.git"
18
+ },
19
+ "homepage": "https://github.com/ApiRTC/expo-apirtc-options-plugin#readme",
15
20
  "dependencies": {
16
21
  "@expo/config-plugins": "^10.1.2",
17
22
  "@types/node": "^24.0.12",