runcloud 0.2.153 → 0.2.154

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.
@@ -289,7 +289,19 @@ function patternItem(root, item, regex, statusOnHit, messageOnHit, messageOnMiss
289
289
  return makeItem(item, statusOnHit, messageOnHit, evidence(matches));
290
290
  return makeItem(item, 'pass', messageOnMiss, `scan: no matches for ${regex}`);
291
291
  }
292
- const MICROPHONE_USE = /expo-av|AudioRecorder|requestRecordingPermissionsAsync|requestMicrophonePermissions/i;
292
+ const MICROPHONE_USE = /expo-av|AudioRecorder|requestRecordingPermissionsAsync|requestMicrophonePermissions|useMicrophonePermissions|recordAsync/i;
293
+ const CAMERA_USE = /expo-camera|CameraView|requestCameraPermissions|launchCameraAsync/i;
294
+ const LOCATION_USE = /expo-location|getCurrentPositionAsync|watchPositionAsync/i;
295
+ const ANDROID_PACKAGE_PERMISSIONS = [
296
+ { pkg: 'expo-camera', permissions: ['CAMERA'] },
297
+ { pkg: 'expo-camera', option: 'recordAudioAndroid', permissions: ['RECORD_AUDIO'] },
298
+ { pkg: 'expo-image-picker', permissions: ['CAMERA', 'READ_EXTERNAL_STORAGE'] },
299
+ { pkg: 'expo-image-picker', option: 'microphonePermission', permissions: ['RECORD_AUDIO'] },
300
+ { pkg: 'expo-audio', option: 'recordAudioAndroid', permissions: ['RECORD_AUDIO'] },
301
+ { pkg: 'expo-location', permissions: ['ACCESS_COARSE_LOCATION', 'ACCESS_FINE_LOCATION'] },
302
+ { pkg: 'expo-media-library', permissions: ['READ_EXTERNAL_STORAGE'] },
303
+ { pkg: 'expo-notifications', permissions: ['POST_NOTIFICATIONS'] },
304
+ ];
293
305
  function isFirebaseClientKey(root, match) {
294
306
  if (!/AIza[0-9A-Za-z_-]{30,}/.test(match.text))
295
307
  return false;
@@ -301,19 +313,36 @@ function isFirebaseClientKey(root, match) {
301
313
  }
302
314
  function missingPermissionRequirements(root, appJson) {
303
315
  const missing = [...missingIosUsageDescriptions(root, appJson)];
304
- const permissions = arrayOfStrings(getPath(appJson, ['expo', 'android', 'permissions']));
316
+ const bare = (permission) => permission.replace(/^android\.permission\./, '');
317
+ const blocked = new Set(arrayOfStrings(getPath(appJson, ['expo', 'android', 'blockedPermissions'])).map(bare));
318
+ const picker = configPluginOptions(appJson, 'expo-image-picker');
319
+ if (picker?.cameraPermission === false)
320
+ blocked.add('CAMERA');
321
+ if (picker?.microphonePermission === false)
322
+ blocked.add('RECORD_AUDIO');
323
+ const installed = installedPackages(root);
324
+ const granted = new Set(arrayOfStrings(getPath(appJson, ['expo', 'android', 'permissions'])).map(bare));
325
+ for (const { pkg, option, permissions } of ANDROID_PACKAGE_PERMISSIONS) {
326
+ const listed = configPluginOptions(appJson, pkg);
327
+ const auto = PLUGIN_PURPOSE_STRINGS[pkg]?.auto ?? false;
328
+ const adds = option === undefined
329
+ ? installed.has(pkg) || listed !== undefined
330
+ : listed ? listed[option] !== false : auto && installed.has(pkg);
331
+ if (adds)
332
+ permissions.forEach((permission) => granted.add(permission));
333
+ }
305
334
  const source = sourceText(root, ['app', 'src', 'components']);
306
335
  const androidChecks = [
307
- { name: 'camera', used: /expo-camera|CameraView|requestCameraPermissions/i, permissions: ['CAMERA'] },
308
- { name: 'location', used: /expo-location|getCurrentPositionAsync|watchPositionAsync/i, permissions: ['ACCESS_FINE_LOCATION', 'ACCESS_COARSE_LOCATION'] },
309
- { name: 'photos', used: /expo-image-picker|expo-media-library|MediaLibrary/i, permissions: ['READ_MEDIA_IMAGES', 'READ_EXTERNAL_STORAGE'] },
336
+ { name: 'camera', used: CAMERA_USE, permissions: ['CAMERA'] },
337
+ { name: 'location', used: LOCATION_USE, permissions: ['ACCESS_FINE_LOCATION', 'ACCESS_COARSE_LOCATION'] },
338
+ { name: 'photos', used: /expo-media-library|MediaLibrary/i, permissions: ['READ_MEDIA_IMAGES', 'READ_EXTERNAL_STORAGE'] },
310
339
  { name: 'microphone', used: MICROPHONE_USE, permissions: ['RECORD_AUDIO'] },
311
340
  { name: 'notifications', used: /expo-notifications/i, permissions: ['POST_NOTIFICATIONS'] },
312
341
  ];
313
342
  for (const check of androidChecks) {
314
343
  if (!check.used.test(source))
315
344
  continue;
316
- if (!check.permissions.some((permission) => permissions.includes(permission))) {
345
+ if (!check.permissions.some((permission) => granted.has(permission) && !blocked.has(permission))) {
317
346
  missing.push(`android ${check.name} permission (${check.permissions.join(' or ')})`);
318
347
  }
319
348
  }
@@ -323,13 +352,12 @@ function missingIosUsageDescriptions(root, appJson) {
323
352
  const infoPlist = objectValue(getPath(appJson, ['expo', 'ios', 'infoPlist']));
324
353
  const source = sourceText(root, ['app', 'src', 'components']);
325
354
  const checks = [
326
- { name: 'camera', used: /expo-camera|CameraView|requestCameraPermissions/i, keys: ['NSCameraUsageDescription'] },
327
- { name: 'location', used: /expo-location|getCurrentPositionAsync|watchPositionAsync/i, keys: ['NSLocationWhenInUseUsageDescription', 'NSLocationAlwaysAndWhenInUseUsageDescription'] },
355
+ { name: 'camera', used: CAMERA_USE, keys: ['NSCameraUsageDescription'] },
356
+ { name: 'location', used: LOCATION_USE, keys: ['NSLocationWhenInUseUsageDescription', 'NSLocationAlwaysAndWhenInUseUsageDescription'] },
328
357
  { name: 'photos', used: /expo-image-picker|expo-media-library|MediaLibrary/i, keys: ['NSPhotoLibraryUsageDescription'] },
329
358
  { name: 'microphone', used: MICROPHONE_USE, keys: ['NSMicrophoneUsageDescription'] },
330
359
  ];
331
- const pkg = readJson(path.join(root, 'package.json'));
332
- const installed = new Set(['dependencies', 'devDependencies'].flatMap((field) => Object.keys(objectValue(getPath(pkg, [field])))));
360
+ const installed = installedPackages(root);
333
361
  const missing = [];
334
362
  for (const check of checks) {
335
363
  if (!check.used.test(source))
@@ -370,6 +398,10 @@ function builtWithPurposeString(key, infoPlist, appJson, installed) {
370
398
  }
371
399
  return written;
372
400
  }
401
+ function installedPackages(root) {
402
+ const pkg = readJson(path.join(root, 'package.json'));
403
+ return new Set(['dependencies', 'devDependencies'].flatMap((field) => Object.keys(objectValue(getPath(pkg, [field])))));
404
+ }
373
405
  function configPluginOptions(appJson, name) {
374
406
  const plugins = getPath(appJson, ['expo', 'plugins']);
375
407
  if (!Array.isArray(plugins))
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const CLI_VERSION = '0.2.153';
1
+ export const CLI_VERSION = '0.2.154';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runcloud",
3
- "version": "0.2.153",
3
+ "version": "0.2.154",
4
4
  "description": "Create and control run.cloud remote mobile simulators and cloud sandboxes",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
Binary file
Binary file