erne-universal 0.10.8 → 0.10.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.
Files changed (2) hide show
  1. package/lib/audit.js +31 -6
  2. package/package.json +1 -1
package/lib/audit.js CHANGED
@@ -869,6 +869,31 @@ function checkPermissions(cwd, deps, findings, strengths) {
869
869
  const declaredIosKeys = new Set(Object.keys(infoPlist));
870
870
  const declaredAndroidPerms = new Set(androidPermissions);
871
871
 
872
+ // Expo plugins automatically add permissions at build time
873
+ // Map plugin names to the permissions they auto-configure
874
+ const plugins = expo?.plugins || [];
875
+ const pluginNames = new Set(plugins.map(p => Array.isArray(p) ? p[0] : p));
876
+ const PLUGIN_PERMISSIONS = {
877
+ 'expo-camera': { iosKeys: ['NSCameraUsageDescription', 'NSMicrophoneUsageDescription'], androidPerms: ['android.permission.CAMERA'] },
878
+ 'expo-location': { iosKeys: ['NSLocationWhenInUseUsageDescription', 'NSLocationAlwaysUsageDescription', 'NSLocationAlwaysAndWhenInUseUsageDescription'], androidPerms: ['android.permission.ACCESS_FINE_LOCATION', 'android.permission.ACCESS_COARSE_LOCATION'] },
879
+ 'expo-av': { iosKeys: ['NSMicrophoneUsageDescription'], androidPerms: ['android.permission.RECORD_AUDIO'] },
880
+ 'expo-audio': { iosKeys: ['NSMicrophoneUsageDescription'], androidPerms: ['android.permission.RECORD_AUDIO'] },
881
+ 'expo-media-library': { iosKeys: ['NSPhotoLibraryUsageDescription', 'NSPhotoLibraryAddUsageDescription'], androidPerms: ['android.permission.READ_MEDIA_IMAGES'] },
882
+ 'expo-image-picker': { iosKeys: ['NSCameraUsageDescription', 'NSPhotoLibraryUsageDescription'], androidPerms: ['android.permission.CAMERA'] },
883
+ 'expo-contacts': { iosKeys: ['NSContactsUsageDescription'], androidPerms: ['android.permission.READ_CONTACTS'] },
884
+ 'expo-calendar': { iosKeys: ['NSCalendarsUsageDescription'], androidPerms: ['android.permission.READ_CALENDAR'] },
885
+ 'expo-notifications': { iosKeys: [], androidPerms: [] },
886
+ };
887
+
888
+ // Add plugin-provided permissions to declared sets
889
+ for (const pluginName of pluginNames) {
890
+ const pluginPerms = PLUGIN_PERMISSIONS[pluginName];
891
+ if (pluginPerms) {
892
+ for (const key of pluginPerms.iosKeys) declaredIosKeys.add(key);
893
+ for (const perm of pluginPerms.androidPerms) declaredAndroidPerms.add(perm);
894
+ }
895
+ }
896
+
872
897
  let missingCount = 0;
873
898
  let installedPermCount = 0;
874
899
  const usedIosKeys = new Set();
@@ -884,27 +909,27 @@ function checkPermissions(cwd, deps, findings, strengths) {
884
909
  if (api.iosKey) usedIosKeys.add(api.iosKey);
885
910
  if (api.androidPerm) usedAndroidPerms.add(api.androidPerm);
886
911
 
887
- // Check iOS plist declaration
912
+ // Check iOS plist declaration (manual infoPlist OR plugin-provided)
888
913
  if (api.iosKey && appConfig && !declaredIosKeys.has(api.iosKey)) {
889
914
  missingCount++;
890
915
  findings.push({
891
916
  severity: SEVERITY.critical,
892
917
  category: CATEGORY.permissions,
893
918
  title: `Missing iOS permission: ${api.iosKey}`,
894
- detail: `${installed.join(', ')} requires ${name} permission but ${api.iosKey} is not declared in app.json ios.infoPlist.`,
895
- fix: `Add "${api.iosKey}" to app.json > expo > ios > infoPlist`,
919
+ detail: `${installed.join(', ')} requires ${name} permission but ${api.iosKey} is not declared in app.json ios.infoPlist and no matching Expo plugin found.`,
920
+ fix: `Add "${api.iosKey}" to app.json > expo > ios > infoPlist, or add the corresponding Expo plugin`,
896
921
  });
897
922
  }
898
923
 
899
- // Check Android permission declaration
924
+ // Check Android permission declaration (manual OR plugin-provided)
900
925
  if (api.androidPerm && appConfig && androidPermissions.length > 0 && !declaredAndroidPerms.has(api.androidPerm)) {
901
926
  missingCount++;
902
927
  findings.push({
903
928
  severity: SEVERITY.critical,
904
929
  category: CATEGORY.permissions,
905
930
  title: `Missing Android permission: ${api.androidPerm}`,
906
- detail: `${installed.join(', ')} requires ${name} permission but ${api.androidPerm} is not declared in app.json android.permissions.`,
907
- fix: `Add "${api.androidPerm}" to app.json > expo > android > permissions`,
931
+ detail: `${installed.join(', ')} requires ${name} permission but ${api.androidPerm} is not declared in app.json android.permissions and no matching Expo plugin found.`,
932
+ fix: `Add "${api.androidPerm}" to app.json > expo > android > permissions, or add the corresponding Expo plugin`,
908
933
  });
909
934
  }
910
935
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "erne-universal",
3
- "version": "0.10.8",
3
+ "version": "0.10.9",
4
4
  "description": "Complete AI coding agent harness for React Native and Expo development",
5
5
  "keywords": [
6
6
  "react-native",