@expo/config-plugins 4.0.10 → 4.0.14

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 (40) hide show
  1. package/build/android/IntentFilters.d.ts +3 -3
  2. package/build/android/IntentFilters.js +44 -48
  3. package/build/android/IntentFilters.js.map +1 -1
  4. package/build/android/Manifest.d.ts +8 -1
  5. package/build/android/Manifest.js +3 -1
  6. package/build/android/Manifest.js.map +1 -1
  7. package/build/android/Permissions.d.ts +2 -0
  8. package/build/android/Permissions.js +88 -3
  9. package/build/android/Permissions.js.map +1 -1
  10. package/build/android/Updates.d.ts +2 -2
  11. package/build/android/Updates.js +20 -4
  12. package/build/android/Updates.js.map +1 -1
  13. package/build/android/Version.d.ts +9 -0
  14. package/build/android/Version.js +37 -1
  15. package/build/android/Version.js.map +1 -1
  16. package/build/ios/BundleIdentifier.js +11 -1
  17. package/build/ios/BundleIdentifier.js.map +1 -1
  18. package/build/ios/Maps.d.ts +3 -5
  19. package/build/ios/Maps.js +29 -34
  20. package/build/ios/Maps.js.map +1 -1
  21. package/build/ios/Name.d.ts +7 -2
  22. package/build/ios/Name.js +58 -1
  23. package/build/ios/Name.js.map +1 -1
  24. package/build/ios/ProvisioningProfile.js +11 -2
  25. package/build/ios/ProvisioningProfile.js.map +1 -1
  26. package/build/ios/Target.js +29 -10
  27. package/build/ios/Target.js.map +1 -1
  28. package/build/ios/Updates.d.ts +2 -2
  29. package/build/ios/Updates.js +20 -4
  30. package/build/ios/Updates.js.map +1 -1
  31. package/build/ios/utils/string.d.ts +1 -0
  32. package/build/ios/utils/string.js +11 -0
  33. package/build/ios/utils/string.js.map +1 -0
  34. package/build/utils/Updates.d.ts +1 -0
  35. package/build/utils/Updates.js +34 -0
  36. package/build/utils/Updates.js.map +1 -1
  37. package/package.json +2 -1
  38. package/build/utils/resolvePackageRootFolder.d.ts +0 -1
  39. package/build/utils/resolvePackageRootFolder.js +0 -57
  40. package/build/utils/resolvePackageRootFolder.js.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import { Android, ExpoConfig } from '@expo/config-types';
2
- import { AndroidManifest } from './Manifest';
2
+ import { AndroidManifest, ManifestIntentFilter } from './Manifest';
3
3
  declare type AndroidIntentFilters = NonNullable<Android['intentFilters']>;
4
4
  export declare const withAndroidIntentFilters: import("..").ConfigPlugin<void>;
5
5
  export declare function getIntentFilters(config: Pick<ExpoConfig, 'android'>): AndroidIntentFilters;
6
- export declare function setAndroidIntentFilters(config: Pick<ExpoConfig, 'android'>, androidManifest: AndroidManifest): Promise<AndroidManifest>;
7
- export default function renderIntentFilters(intentFilters: AndroidIntentFilters): string[];
6
+ export declare function setAndroidIntentFilters(config: Pick<ExpoConfig, 'android'>, androidManifest: AndroidManifest): AndroidManifest;
7
+ export default function renderIntentFilters(intentFilters: AndroidIntentFilters): ManifestIntentFilter[];
8
8
  export {};
@@ -8,16 +8,6 @@ exports.getIntentFilters = getIntentFilters;
8
8
  exports.setAndroidIntentFilters = setAndroidIntentFilters;
9
9
  exports.withAndroidIntentFilters = void 0;
10
10
 
11
- function _xml2js() {
12
- const data = require("xml2js");
13
-
14
- _xml2js = function () {
15
- return data;
16
- };
17
-
18
- return data;
19
- }
20
-
21
11
  function _androidPlugins() {
22
12
  const data = require("../plugins/android-plugins");
23
13
 
@@ -38,7 +28,7 @@ function _Manifest() {
38
28
  return data;
39
29
  }
40
30
 
41
- // TODO: make it so intent filters aren't written again if you run the command again
31
+ const GENERATED_TAG = 'data-generated';
42
32
  const withAndroidIntentFilters = (0, _androidPlugins().createAndroidManifestPlugin)(setAndroidIntentFilters, 'withAndroidIntentFilters');
43
33
  exports.withAndroidIntentFilters = withAndroidIntentFilters;
44
34
 
@@ -48,8 +38,19 @@ function getIntentFilters(config) {
48
38
  return (_config$android$inten = (_config$android = config.android) === null || _config$android === void 0 ? void 0 : _config$android.intentFilters) !== null && _config$android$inten !== void 0 ? _config$android$inten : [];
49
39
  }
50
40
 
51
- async function setAndroidIntentFilters(config, androidManifest) {
52
- var _mainActivity$intent;
41
+ function setAndroidIntentFilters(config, androidManifest) {
42
+ var _mainActivity$intent, _mainActivity$intent2;
43
+
44
+ // Always ensure old tags are removed.
45
+ const mainActivity = (0, _Manifest().getMainActivityOrThrow)(androidManifest); // Remove all generated tags from previous runs...
46
+
47
+ if ((_mainActivity$intent = mainActivity['intent-filter']) !== null && _mainActivity$intent !== void 0 && _mainActivity$intent.length) {
48
+ mainActivity['intent-filter'] = mainActivity['intent-filter'].filter(value => {
49
+ var _value$$;
50
+
51
+ return ((_value$$ = value.$) === null || _value$$ === void 0 ? void 0 : _value$$[GENERATED_TAG]) !== 'true';
52
+ });
53
+ }
53
54
 
54
55
  const intentFilters = getIntentFilters(config);
55
56
 
@@ -57,53 +58,48 @@ async function setAndroidIntentFilters(config, androidManifest) {
57
58
  return androidManifest;
58
59
  }
59
60
 
60
- const intentFiltersXML = renderIntentFilters(intentFilters).join('');
61
- const parser = new (_xml2js().Parser)();
62
- const intentFiltersJSON = await parser.parseStringPromise(intentFiltersXML);
63
- const mainActivity = (0, _Manifest().getMainActivityOrThrow)(androidManifest);
64
- mainActivity['intent-filter'] = (_mainActivity$intent = mainActivity['intent-filter']) === null || _mainActivity$intent === void 0 ? void 0 : _mainActivity$intent.concat(intentFiltersJSON['intent-filter']);
61
+ mainActivity['intent-filter'] = (_mainActivity$intent2 = mainActivity['intent-filter']) === null || _mainActivity$intent2 === void 0 ? void 0 : _mainActivity$intent2.concat(renderIntentFilters(intentFilters));
65
62
  return androidManifest;
66
63
  }
67
64
 
68
65
  function renderIntentFilters(intentFilters) {
69
- // returns an array of <intent-filter> tags:
70
- // [
71
- // `<intent-filter>
72
- // <data android:scheme="exp"/>
73
- // <data android:scheme="exps"/>
74
- //
75
- // <action android:name="android.intent.action.VIEW"/>
76
- //
77
- // <category android:name="android.intent.category.DEFAULT"/>
78
- // <category android:name="android.intent.category.BROWSABLE"/>
79
- // </intent-filter>`,
80
- // ...
81
- // ]
82
66
  return intentFilters.map(intentFilter => {
83
- const autoVerify = intentFilter.autoVerify ? ' android:autoVerify="true"' : '';
84
- return `<intent-filter${autoVerify}>
85
- ${renderIntentFilterData(intentFilter.data)}
86
- <action android:name="android.intent.action.${intentFilter.action}"/>
87
- ${renderIntentFilterCategory(intentFilter.category)}
88
- </intent-filter>`;
67
+ // <intent-filter>
68
+ return {
69
+ $: {
70
+ 'android:autoVerify': intentFilter.autoVerify ? 'true' : undefined,
71
+ // Add a custom "generated" tag that we can query later to remove.
72
+ [GENERATED_TAG]: 'true'
73
+ },
74
+ action: [// <action android:name="android.intent.action.VIEW"/>
75
+ {
76
+ $: {
77
+ 'android:name': `android.intent.action.${intentFilter.action}`
78
+ }
79
+ }],
80
+ data: renderIntentFilterData(intentFilter.data),
81
+ category: renderIntentFilterCategory(intentFilter.category)
82
+ };
89
83
  });
90
84
  }
85
+ /** Like `<data android:scheme="exp"/>` */
91
86
 
92
- function renderIntentFilterDatumEntries(datum = {}) {
93
- const entries = [];
94
-
95
- for (const [key, value] of Object.entries(datum)) {
96
- entries.push(`android:${key}="${value}"`);
97
- }
98
-
99
- return entries.join(' ');
100
- }
101
87
 
102
88
  function renderIntentFilterData(data) {
103
- return (Array.isArray(data) ? data : [data]).filter(Boolean).map(datum => `<data ${renderIntentFilterDatumEntries(datum)}/>`).join('\n');
89
+ return (Array.isArray(data) ? data : [data]).filter(Boolean).map(datum => ({
90
+ $: Object.entries(datum !== null && datum !== void 0 ? datum : {}).reduce((prev, [key, value]) => ({ ...prev,
91
+ [`android:${key}`]: value
92
+ }), {})
93
+ }));
104
94
  }
95
+ /** Like `<category android:name="android.intent.category.DEFAULT"/>` */
96
+
105
97
 
106
98
  function renderIntentFilterCategory(category) {
107
- return (Array.isArray(category) ? category : [category]).filter(Boolean).map(cat => `<category android:name="android.intent.category.${cat}"/>`).join('\n');
99
+ return (Array.isArray(category) ? category : [category]).filter(Boolean).map(cat => ({
100
+ $: {
101
+ 'android:name': `android.intent.category.${cat}`
102
+ }
103
+ }));
108
104
  }
109
105
  //# sourceMappingURL=IntentFilters.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/android/IntentFilters.ts"],"names":["withAndroidIntentFilters","setAndroidIntentFilters","getIntentFilters","config","android","intentFilters","androidManifest","length","intentFiltersXML","renderIntentFilters","join","parser","Parser","intentFiltersJSON","parseStringPromise","mainActivity","concat","map","intentFilter","autoVerify","renderIntentFilterData","data","action","renderIntentFilterCategory","category","renderIntentFilterDatumEntries","datum","entries","key","value","Object","push","Array","isArray","filter","Boolean","cat"],"mappings":";;;;;;;;;;AACA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAEA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AACA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAGA;AAEO,MAAMA,wBAAwB,GAAG,mDACtCC,uBADsC,EAEtC,0BAFsC,CAAjC;;;AAKA,SAASC,gBAAT,CAA0BC,MAA1B,EAAqF;AAAA;;AAC1F,qDAAOA,MAAM,CAACC,OAAd,oDAAO,gBAAgBC,aAAvB,yEAAwC,EAAxC;AACD;;AAEM,eAAeJ,uBAAf,CACLE,MADK,EAELG,eAFK,EAGqB;AAAA;;AAC1B,QAAMD,aAAa,GAAGH,gBAAgB,CAACC,MAAD,CAAtC;;AACA,MAAI,CAACE,aAAa,CAACE,MAAnB,EAA2B;AACzB,WAAOD,eAAP;AACD;;AAED,QAAME,gBAAgB,GAAGC,mBAAmB,CAACJ,aAAD,CAAnB,CAAmCK,IAAnC,CAAwC,EAAxC,CAAzB;AACA,QAAMC,MAAM,GAAG,KAAIC,gBAAJ,GAAf;AACA,QAAMC,iBAAiB,GAAG,MAAMF,MAAM,CAACG,kBAAP,CAA0BN,gBAA1B,CAAhC;AAEA,QAAMO,YAAY,GAAG,wCAAuBT,eAAvB,CAArB;AAEAS,EAAAA,YAAY,CAAC,eAAD,CAAZ,2BAAgCA,YAAY,CAAC,eAAD,CAA5C,yDAAgC,qBAA+BC,MAA/B,CAC9BH,iBAAiB,CAAC,eAAD,CADa,CAAhC;AAIA,SAAOP,eAAP;AACD;;AAEc,SAASG,mBAAT,CAA6BJ,aAA7B,EAA4E;AACzF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAOA,aAAa,CAACY,GAAd,CAAkBC,YAAY,IAAI;AACvC,UAAMC,UAAU,GAAGD,YAAY,CAACC,UAAb,GAA0B,4BAA1B,GAAyD,EAA5E;AAEA,WAAQ,iBAAgBA,UAAW;AACvC,QAAQC,sBAAsB,CAACF,YAAY,CAACG,IAAd,CAAoB;AAClD,oDAAoDH,YAAY,CAACI,MAAO;AACxE,QAAQC,0BAA0B,CAACL,YAAY,CAACM,QAAd,CAAwB;AAC1D,qBAJI;AAKD,GARM,CAAP;AASD;;AAED,SAASC,8BAAT,CAAwCC,KAA+B,GAAG,EAA1E,EAAsF;AACpF,QAAMC,OAAiB,GAAG,EAA1B;;AACA,OAAK,MAAM,CAACC,GAAD,EAAMC,KAAN,CAAX,IAA2BC,MAAM,CAACH,OAAP,CAAeD,KAAf,CAA3B,EAAkD;AAChDC,IAAAA,OAAO,CAACI,IAAR,CAAc,WAAUH,GAAI,KAAIC,KAAM,GAAtC;AACD;;AACD,SAAOF,OAAO,CAACjB,IAAR,CAAa,GAAb,CAAP;AACD;;AAED,SAASU,sBAAT,CACEC,IADF,EAEU;AACR,SAAO,CAACW,KAAK,CAACC,OAAN,CAAcZ,IAAd,IAAsBA,IAAtB,GAA6B,CAACA,IAAD,CAA9B,EACJa,MADI,CACGC,OADH,EAEJlB,GAFI,CAEAS,KAAK,IAAK,SAAQD,8BAA8B,CAACC,KAAD,CAAQ,IAFxD,EAGJhB,IAHI,CAGC,IAHD,CAAP;AAID;;AAED,SAASa,0BAAT,CAAoCC,QAApC,EAA0E;AACxE,SAAO,CAACQ,KAAK,CAACC,OAAN,CAAcT,QAAd,IAA0BA,QAA1B,GAAqC,CAACA,QAAD,CAAtC,EACJU,MADI,CACGC,OADH,EAEJlB,GAFI,CAEAmB,GAAG,IAAK,mDAAkDA,GAAI,KAF9D,EAGJ1B,IAHI,CAGC,IAHD,CAAP;AAID","sourcesContent":["import { Android, AndroidIntentFiltersData, ExpoConfig } from '@expo/config-types';\nimport { Parser } from 'xml2js';\n\nimport { createAndroidManifestPlugin } from '../plugins/android-plugins';\nimport { AndroidManifest, getMainActivityOrThrow } from './Manifest';\n\ntype AndroidIntentFilters = NonNullable<Android['intentFilters']>;\n// TODO: make it so intent filters aren't written again if you run the command again\n\nexport const withAndroidIntentFilters = createAndroidManifestPlugin(\n setAndroidIntentFilters,\n 'withAndroidIntentFilters'\n);\n\nexport function getIntentFilters(config: Pick<ExpoConfig, 'android'>): AndroidIntentFilters {\n return config.android?.intentFilters ?? [];\n}\n\nexport async function setAndroidIntentFilters(\n config: Pick<ExpoConfig, 'android'>,\n androidManifest: AndroidManifest\n): Promise<AndroidManifest> {\n const intentFilters = getIntentFilters(config);\n if (!intentFilters.length) {\n return androidManifest;\n }\n\n const intentFiltersXML = renderIntentFilters(intentFilters).join('');\n const parser = new Parser();\n const intentFiltersJSON = await parser.parseStringPromise(intentFiltersXML);\n\n const mainActivity = getMainActivityOrThrow(androidManifest);\n\n mainActivity['intent-filter'] = mainActivity['intent-filter']?.concat(\n intentFiltersJSON['intent-filter']\n );\n\n return androidManifest;\n}\n\nexport default function renderIntentFilters(intentFilters: AndroidIntentFilters): string[] {\n // returns an array of <intent-filter> tags:\n // [\n // `<intent-filter>\n // <data android:scheme=\"exp\"/>\n // <data android:scheme=\"exps\"/>\n //\n // <action android:name=\"android.intent.action.VIEW\"/>\n //\n // <category android:name=\"android.intent.category.DEFAULT\"/>\n // <category android:name=\"android.intent.category.BROWSABLE\"/>\n // </intent-filter>`,\n // ...\n // ]\n return intentFilters.map(intentFilter => {\n const autoVerify = intentFilter.autoVerify ? ' android:autoVerify=\"true\"' : '';\n\n return `<intent-filter${autoVerify}>\n ${renderIntentFilterData(intentFilter.data)}\n <action android:name=\"android.intent.action.${intentFilter.action}\"/>\n ${renderIntentFilterCategory(intentFilter.category)}\n </intent-filter>`;\n });\n}\n\nfunction renderIntentFilterDatumEntries(datum: AndroidIntentFiltersData = {}): string {\n const entries: string[] = [];\n for (const [key, value] of Object.entries(datum)) {\n entries.push(`android:${key}=\"${value}\"`);\n }\n return entries.join(' ');\n}\n\nfunction renderIntentFilterData(\n data?: AndroidIntentFiltersData | AndroidIntentFiltersData[]\n): string {\n return (Array.isArray(data) ? data : [data])\n .filter(Boolean)\n .map(datum => `<data ${renderIntentFilterDatumEntries(datum)}/>`)\n .join('\\n');\n}\n\nfunction renderIntentFilterCategory(category?: string | string[]): string {\n return (Array.isArray(category) ? category : [category])\n .filter(Boolean)\n .map(cat => `<category android:name=\"android.intent.category.${cat}\"/>`)\n .join('\\n');\n}\n"],"file":"IntentFilters.js"}
1
+ {"version":3,"sources":["../../src/android/IntentFilters.ts"],"names":["GENERATED_TAG","withAndroidIntentFilters","setAndroidIntentFilters","getIntentFilters","config","android","intentFilters","androidManifest","mainActivity","length","filter","value","$","concat","renderIntentFilters","map","intentFilter","autoVerify","undefined","action","data","renderIntentFilterData","category","renderIntentFilterCategory","Array","isArray","Boolean","datum","Object","entries","reduce","prev","key","cat"],"mappings":"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","sourcesContent":["import { Android, AndroidIntentFiltersData, ExpoConfig } from '@expo/config-types';\n\nimport { createAndroidManifestPlugin } from '../plugins/android-plugins';\nimport { AndroidManifest, getMainActivityOrThrow, ManifestIntentFilter } from './Manifest';\n\ntype AndroidIntentFilters = NonNullable<Android['intentFilters']>;\n\nconst GENERATED_TAG = 'data-generated';\n\nexport const withAndroidIntentFilters = createAndroidManifestPlugin(\n setAndroidIntentFilters,\n 'withAndroidIntentFilters'\n);\n\nexport function getIntentFilters(config: Pick<ExpoConfig, 'android'>): AndroidIntentFilters {\n return config.android?.intentFilters ?? [];\n}\n\nexport function setAndroidIntentFilters(\n config: Pick<ExpoConfig, 'android'>,\n androidManifest: AndroidManifest\n): AndroidManifest {\n // Always ensure old tags are removed.\n const mainActivity = getMainActivityOrThrow(androidManifest);\n // Remove all generated tags from previous runs...\n if (mainActivity['intent-filter']?.length) {\n mainActivity['intent-filter'] = mainActivity['intent-filter'].filter(\n value => value.$?.[GENERATED_TAG] !== 'true'\n );\n }\n\n const intentFilters = getIntentFilters(config);\n if (!intentFilters.length) {\n return androidManifest;\n }\n\n mainActivity['intent-filter'] = mainActivity['intent-filter']?.concat(\n renderIntentFilters(intentFilters)\n );\n\n return androidManifest;\n}\n\nexport default function renderIntentFilters(\n intentFilters: AndroidIntentFilters\n): ManifestIntentFilter[] {\n return intentFilters.map(intentFilter => {\n // <intent-filter>\n return {\n $: {\n 'android:autoVerify': intentFilter.autoVerify ? 'true' : undefined,\n // Add a custom \"generated\" tag that we can query later to remove.\n [GENERATED_TAG]: 'true',\n },\n action: [\n // <action android:name=\"android.intent.action.VIEW\"/>\n {\n $: {\n 'android:name': `android.intent.action.${intentFilter.action}`,\n },\n },\n ],\n data: renderIntentFilterData(intentFilter.data),\n category: renderIntentFilterCategory(intentFilter.category),\n };\n });\n}\n\n/** Like `<data android:scheme=\"exp\"/>` */\nfunction renderIntentFilterData(data?: AndroidIntentFiltersData | AndroidIntentFiltersData[]) {\n return (Array.isArray(data) ? data : [data]).filter(Boolean).map(datum => ({\n $: Object.entries(datum ?? {}).reduce(\n (prev, [key, value]) => ({ ...prev, [`android:${key}`]: value }),\n {}\n ),\n }));\n}\n\n/** Like `<category android:name=\"android.intent.category.DEFAULT\"/>` */\nfunction renderIntentFilterCategory(category?: string | string[]) {\n return (Array.isArray(category) ? category : [category]).filter(Boolean).map(cat => ({\n $: {\n 'android:name': `android.intent.category.${cat}`,\n },\n }));\n}\n"],"file":"IntentFilters.js"}
@@ -5,6 +5,7 @@ declare type ManifestMetaDataAttributes = AndroidManifestAttributes & {
5
5
  };
6
6
  declare type AndroidManifestAttributes = {
7
7
  'android:name': string | 'android.intent.action.VIEW';
8
+ 'tools:node'?: string | 'remove';
8
9
  };
9
10
  declare type ManifestAction = {
10
11
  $: AndroidManifestAttributes;
@@ -27,7 +28,11 @@ declare type ManifestReceiver = {
27
28
  };
28
29
  'intent-filter'?: ManifestIntentFilter[];
29
30
  };
30
- declare type ManifestIntentFilter = {
31
+ export declare type ManifestIntentFilter = {
32
+ $?: {
33
+ 'android:autoVerify'?: StringBoolean;
34
+ 'data-generated'?: StringBoolean;
35
+ };
31
36
  action?: ManifestAction[];
32
37
  data?: ManifestData[];
33
38
  category?: ManifestCategory[];
@@ -95,6 +100,7 @@ export declare type AndroidManifest = {
95
100
  manifest: {
96
101
  $: {
97
102
  'xmlns:android': string;
103
+ 'xmlns:tools'?: string;
98
104
  package?: string;
99
105
  [key: string]: string | undefined;
100
106
  };
@@ -107,6 +113,7 @@ export declare type AndroidManifest = {
107
113
  };
108
114
  export declare function writeAndroidManifestAsync(manifestPath: string, androidManifest: AndroidManifest): Promise<void>;
109
115
  export declare function readAndroidManifestAsync(manifestPath: string): Promise<AndroidManifest>;
116
+ /** Returns the `manifest.application` tag ending in `.MainApplication` */
110
117
  export declare function getMainApplication(androidManifest: AndroidManifest): ManifestApplication | null;
111
118
  export declare function getMainApplicationOrThrow(androidManifest: AndroidManifest): ManifestApplication;
112
119
  export declare function getMainActivityOrThrow(androidManifest: AndroidManifest): ManifestActivity;
@@ -87,6 +87,8 @@ function isManifest(xml) {
87
87
  // TODO: Maybe more validation
88
88
  return !!xml.manifest;
89
89
  }
90
+ /** Returns the `manifest.application` tag ending in `.MainApplication` */
91
+
90
92
 
91
93
  function getMainApplication(androidManifest) {
92
94
  var _androidManifest$mani, _androidManifest$mani2, _androidManifest$mani3;
@@ -94,7 +96,7 @@ function getMainApplication(androidManifest) {
94
96
  return (_androidManifest$mani = androidManifest === null || androidManifest === void 0 ? void 0 : (_androidManifest$mani2 = androidManifest.manifest) === null || _androidManifest$mani2 === void 0 ? void 0 : (_androidManifest$mani3 = _androidManifest$mani2.application) === null || _androidManifest$mani3 === void 0 ? void 0 : _androidManifest$mani3.filter(e => {
95
97
  var _e$$;
96
98
 
97
- return (e === null || e === void 0 ? void 0 : (_e$$ = e.$) === null || _e$$ === void 0 ? void 0 : _e$$['android:name']) === '.MainApplication';
99
+ return e === null || e === void 0 ? void 0 : (_e$$ = e.$) === null || _e$$ === void 0 ? void 0 : _e$$['android:name'].endsWith('.MainApplication');
98
100
  })[0]) !== null && _androidManifest$mani !== void 0 ? _androidManifest$mani : null;
99
101
  }
100
102
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/android/Manifest.ts"],"names":["writeAndroidManifestAsync","manifestPath","androidManifest","manifestXml","XML","format","fs","ensureDir","path","dirname","writeFile","readAndroidManifestAsync","xml","readXMLAsync","isManifest","Error","manifest","getMainApplication","application","filter","e","$","getMainApplicationOrThrow","mainApplication","getMainActivityOrThrow","mainActivity","getMainActivity","getRunnableActivity","enabledActivities","activity","Array","isArray","intentFilter","action","find","category","addMetaDataItemToMainApplication","itemName","itemValue","itemType","existingMetaDataItem","newItem","prefixAndroidKeys","name","length","push","removeMetaDataItemFromMainApplication","index","findMetaDataItem","splice","findApplicationSubItem","parent","findIndex","findUsesLibraryItem","getMainApplicationMetaDataValue","hasOwnProperty","item","addUsesLibraryItemToMainApplication","removeUsesLibraryItemFromMainApplication","head","Object","entries","reduce","prev","key","curr"],"mappings":"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","sourcesContent":["import assert from 'assert';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nimport * as XML from '../utils/XML';\n\nexport type StringBoolean = 'true' | 'false';\n\ntype ManifestMetaDataAttributes = AndroidManifestAttributes & {\n 'android:value'?: string;\n 'android:resource'?: string;\n};\n\ntype AndroidManifestAttributes = {\n 'android:name': string | 'android.intent.action.VIEW';\n};\n\ntype ManifestAction = {\n $: AndroidManifestAttributes;\n};\n\ntype ManifestCategory = {\n $: AndroidManifestAttributes;\n};\n\ntype ManifestData = {\n $: {\n [key: string]: string | undefined;\n 'android:host'?: string;\n 'android:pathPrefix'?: string;\n 'android:scheme'?: string;\n };\n};\n\ntype ManifestReceiver = {\n $: AndroidManifestAttributes & {\n 'android:exported'?: StringBoolean;\n 'android:enabled'?: StringBoolean;\n };\n 'intent-filter'?: ManifestIntentFilter[];\n};\n\ntype ManifestIntentFilter = {\n action?: ManifestAction[];\n data?: ManifestData[];\n category?: ManifestCategory[];\n};\n\nexport type ManifestMetaData = {\n $: ManifestMetaDataAttributes;\n};\n\ntype ManifestServiceAttributes = AndroidManifestAttributes & {\n 'android:enabled'?: StringBoolean;\n 'android:exported'?: StringBoolean;\n 'android:permission'?: string;\n // ...\n};\n\ntype ManifestService = {\n $: ManifestServiceAttributes;\n 'intent-filter'?: ManifestIntentFilter[];\n};\n\ntype ManifestApplicationAttributes = {\n 'android:name': string | '.MainApplication';\n 'android:icon'?: string;\n 'android:label'?: string;\n 'android:allowBackup'?: StringBoolean;\n 'android:largeHeap'?: StringBoolean;\n 'android:requestLegacyExternalStorage'?: StringBoolean;\n 'android:usesCleartextTraffic'?: StringBoolean;\n [key: string]: string | undefined;\n};\n\nexport type ManifestActivity = {\n $: ManifestApplicationAttributes & {\n 'android:exported'?: StringBoolean;\n 'android:launchMode'?: string;\n 'android:theme'?: string;\n 'android:windowSoftInputMode'?:\n | string\n | 'stateUnspecified'\n | 'stateUnchanged'\n | 'stateHidden'\n | 'stateAlwaysHidden'\n | 'stateVisible'\n | 'stateAlwaysVisible'\n | 'adjustUnspecified'\n | 'adjustResize'\n | 'adjustPan';\n [key: string]: string | undefined;\n };\n 'intent-filter'?: ManifestIntentFilter[];\n // ...\n};\n\nexport type ManifestUsesLibrary = {\n $: AndroidManifestAttributes & {\n 'android:required'?: StringBoolean;\n };\n};\n\nexport type ManifestApplication = {\n $: ManifestApplicationAttributes;\n activity?: ManifestActivity[];\n service?: ManifestService[];\n receiver?: ManifestReceiver[];\n 'meta-data'?: ManifestMetaData[];\n 'uses-library'?: ManifestUsesLibrary[];\n // ...\n};\n\ntype ManifestPermission = {\n $: AndroidManifestAttributes & {\n 'android:protectionLevel'?: string | 'signature';\n };\n};\n\nexport type ManifestUsesPermission = {\n $: AndroidManifestAttributes;\n};\n\ntype ManifestUsesFeature = {\n $: AndroidManifestAttributes & {\n 'android:glEsVersion'?: string;\n 'android:required': StringBoolean;\n };\n};\n\nexport type AndroidManifest = {\n manifest: {\n // Probably more, but this is currently all we'd need for most cases in Expo.\n $: { 'xmlns:android': string; package?: string; [key: string]: string | undefined };\n permission?: ManifestPermission[];\n 'uses-permission'?: ManifestUsesPermission[];\n 'uses-permission-sdk-23'?: ManifestUsesPermission[];\n 'uses-feature'?: ManifestUsesFeature[];\n application?: ManifestApplication[];\n };\n};\n\nexport async function writeAndroidManifestAsync(\n manifestPath: string,\n androidManifest: AndroidManifest\n): Promise<void> {\n const manifestXml = XML.format(androidManifest);\n await fs.ensureDir(path.dirname(manifestPath));\n await fs.writeFile(manifestPath, manifestXml);\n}\n\nexport async function readAndroidManifestAsync(manifestPath: string): Promise<AndroidManifest> {\n const xml = await XML.readXMLAsync({ path: manifestPath });\n if (!isManifest(xml)) {\n throw new Error('Invalid manifest found at: ' + manifestPath);\n }\n return xml;\n}\n\nfunction isManifest(xml: XML.XMLObject): xml is AndroidManifest {\n // TODO: Maybe more validation\n return !!xml.manifest;\n}\n\nexport function getMainApplication(androidManifest: AndroidManifest): ManifestApplication | null {\n return (\n androidManifest?.manifest?.application?.filter(\n e => e?.$?.['android:name'] === '.MainApplication'\n )[0] ?? null\n );\n}\n\nexport function getMainApplicationOrThrow(androidManifest: AndroidManifest): ManifestApplication {\n const mainApplication = getMainApplication(androidManifest);\n assert(mainApplication, 'AndroidManifest.xml is missing the required MainApplication element');\n return mainApplication;\n}\n\nexport function getMainActivityOrThrow(androidManifest: AndroidManifest): ManifestActivity {\n const mainActivity = getMainActivity(androidManifest);\n assert(mainActivity, 'AndroidManifest.xml is missing the required MainActivity element');\n return mainActivity;\n}\n\nexport function getRunnableActivity(androidManifest: AndroidManifest): ManifestActivity | null {\n // Get enabled activities\n const enabledActivities = androidManifest?.manifest?.application?.[0]?.activity?.filter?.(\n (e: any) => e.$['android:enabled'] !== 'false' && e.$['android:enabled'] !== false\n );\n\n if (!enabledActivities) {\n return null;\n }\n\n // Get the activity that has a runnable intent-filter\n for (const activity of enabledActivities) {\n if (Array.isArray(activity['intent-filter'])) {\n for (const intentFilter of activity['intent-filter']) {\n if (\n intentFilter.action?.find(\n action => action.$['android:name'] === 'android.intent.action.MAIN'\n ) &&\n intentFilter.category?.find(\n category => category.$['android:name'] === 'android.intent.category.LAUNCHER'\n )\n ) {\n return activity;\n }\n }\n }\n }\n\n return null;\n}\n\nexport function getMainActivity(androidManifest: AndroidManifest): ManifestActivity | null {\n const mainActivity = androidManifest?.manifest?.application?.[0]?.activity?.filter?.(\n (e: any) => e.$['android:name'] === '.MainActivity'\n );\n return mainActivity?.[0] ?? null;\n}\n\nexport function addMetaDataItemToMainApplication(\n mainApplication: ManifestApplication,\n itemName: string,\n itemValue: string,\n itemType: 'resource' | 'value' = 'value'\n): ManifestApplication {\n let existingMetaDataItem;\n const newItem = {\n $: prefixAndroidKeys({ name: itemName, [itemType]: itemValue }),\n } as ManifestMetaData;\n if (mainApplication['meta-data']) {\n existingMetaDataItem = mainApplication['meta-data'].filter(\n (e: any) => e.$['android:name'] === itemName\n );\n if (existingMetaDataItem.length) {\n existingMetaDataItem[0].$[\n `android:${itemType}` as keyof ManifestMetaDataAttributes\n ] = itemValue;\n } else {\n mainApplication['meta-data'].push(newItem);\n }\n } else {\n mainApplication['meta-data'] = [newItem];\n }\n return mainApplication;\n}\n\nexport function removeMetaDataItemFromMainApplication(mainApplication: any, itemName: string) {\n const index = findMetaDataItem(mainApplication, itemName);\n if (mainApplication?.['meta-data'] && index > -1) {\n mainApplication['meta-data'].splice(index, 1);\n }\n return mainApplication;\n}\n\nfunction findApplicationSubItem(\n mainApplication: ManifestApplication,\n category: keyof ManifestApplication,\n itemName: string\n): number {\n const parent = mainApplication[category];\n if (Array.isArray(parent)) {\n const index = parent.findIndex((e: any) => e.$['android:name'] === itemName);\n\n return index;\n }\n return -1;\n}\n\nexport function findMetaDataItem(mainApplication: any, itemName: string): number {\n return findApplicationSubItem(mainApplication, 'meta-data', itemName);\n}\n\nexport function findUsesLibraryItem(mainApplication: any, itemName: string): number {\n return findApplicationSubItem(mainApplication, 'uses-library', itemName);\n}\n\nexport function getMainApplicationMetaDataValue(\n androidManifest: AndroidManifest,\n name: string\n): string | null {\n const mainApplication = getMainApplication(androidManifest);\n\n if (mainApplication?.hasOwnProperty('meta-data')) {\n const item = mainApplication?.['meta-data']?.find((e: any) => e.$['android:name'] === name);\n return item?.$['android:value'] ?? null;\n }\n\n return null;\n}\n\nexport function addUsesLibraryItemToMainApplication(\n mainApplication: ManifestApplication,\n item: { name: string; required?: boolean }\n): ManifestApplication {\n let existingMetaDataItem;\n const newItem = {\n $: prefixAndroidKeys(item),\n } as ManifestUsesLibrary;\n\n if (mainApplication['uses-library']) {\n existingMetaDataItem = mainApplication['uses-library'].filter(\n e => e.$['android:name'] === item.name\n );\n if (existingMetaDataItem.length) {\n existingMetaDataItem[0].$ = newItem.$;\n } else {\n mainApplication['uses-library'].push(newItem);\n }\n } else {\n mainApplication['uses-library'] = [newItem];\n }\n return mainApplication;\n}\n\nexport function removeUsesLibraryItemFromMainApplication(\n mainApplication: ManifestApplication,\n itemName: string\n) {\n const index = findUsesLibraryItem(mainApplication, itemName);\n if (mainApplication?.['uses-library'] && index > -1) {\n mainApplication['uses-library'].splice(index, 1);\n }\n return mainApplication;\n}\n\nexport function prefixAndroidKeys<T extends Record<string, any> = Record<string, string>>(\n head: T\n): Record<string, any> {\n // prefix all keys with `android:`\n return Object.entries(head).reduce(\n (prev, [key, curr]) => ({ ...prev, [`android:${key}`]: curr }),\n {} as T\n );\n}\n"],"file":"Manifest.js"}
1
+ {"version":3,"sources":["../../src/android/Manifest.ts"],"names":["writeAndroidManifestAsync","manifestPath","androidManifest","manifestXml","XML","format","fs","ensureDir","path","dirname","writeFile","readAndroidManifestAsync","xml","readXMLAsync","isManifest","Error","manifest","getMainApplication","application","filter","e","$","endsWith","getMainApplicationOrThrow","mainApplication","getMainActivityOrThrow","mainActivity","getMainActivity","getRunnableActivity","enabledActivities","activity","Array","isArray","intentFilter","action","find","category","addMetaDataItemToMainApplication","itemName","itemValue","itemType","existingMetaDataItem","newItem","prefixAndroidKeys","name","length","push","removeMetaDataItemFromMainApplication","index","findMetaDataItem","splice","findApplicationSubItem","parent","findIndex","findUsesLibraryItem","getMainApplicationMetaDataValue","hasOwnProperty","item","addUsesLibraryItemToMainApplication","removeUsesLibraryItemFromMainApplication","head","Object","entries","reduce","prev","key","curr"],"mappings":"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","sourcesContent":["import assert from 'assert';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nimport * as XML from '../utils/XML';\n\nexport type StringBoolean = 'true' | 'false';\n\ntype ManifestMetaDataAttributes = AndroidManifestAttributes & {\n 'android:value'?: string;\n 'android:resource'?: string;\n};\n\ntype AndroidManifestAttributes = {\n 'android:name': string | 'android.intent.action.VIEW';\n 'tools:node'?: string | 'remove';\n};\n\ntype ManifestAction = {\n $: AndroidManifestAttributes;\n};\n\ntype ManifestCategory = {\n $: AndroidManifestAttributes;\n};\n\ntype ManifestData = {\n $: {\n [key: string]: string | undefined;\n 'android:host'?: string;\n 'android:pathPrefix'?: string;\n 'android:scheme'?: string;\n };\n};\n\ntype ManifestReceiver = {\n $: AndroidManifestAttributes & {\n 'android:exported'?: StringBoolean;\n 'android:enabled'?: StringBoolean;\n };\n 'intent-filter'?: ManifestIntentFilter[];\n};\n\nexport type ManifestIntentFilter = {\n $?: {\n 'android:autoVerify'?: StringBoolean;\n 'data-generated'?: StringBoolean;\n };\n action?: ManifestAction[];\n data?: ManifestData[];\n category?: ManifestCategory[];\n};\n\nexport type ManifestMetaData = {\n $: ManifestMetaDataAttributes;\n};\n\ntype ManifestServiceAttributes = AndroidManifestAttributes & {\n 'android:enabled'?: StringBoolean;\n 'android:exported'?: StringBoolean;\n 'android:permission'?: string;\n // ...\n};\n\ntype ManifestService = {\n $: ManifestServiceAttributes;\n 'intent-filter'?: ManifestIntentFilter[];\n};\n\ntype ManifestApplicationAttributes = {\n 'android:name': string | '.MainApplication';\n 'android:icon'?: string;\n 'android:label'?: string;\n 'android:allowBackup'?: StringBoolean;\n 'android:largeHeap'?: StringBoolean;\n 'android:requestLegacyExternalStorage'?: StringBoolean;\n 'android:usesCleartextTraffic'?: StringBoolean;\n [key: string]: string | undefined;\n};\n\nexport type ManifestActivity = {\n $: ManifestApplicationAttributes & {\n 'android:exported'?: StringBoolean;\n 'android:launchMode'?: string;\n 'android:theme'?: string;\n 'android:windowSoftInputMode'?:\n | string\n | 'stateUnspecified'\n | 'stateUnchanged'\n | 'stateHidden'\n | 'stateAlwaysHidden'\n | 'stateVisible'\n | 'stateAlwaysVisible'\n | 'adjustUnspecified'\n | 'adjustResize'\n | 'adjustPan';\n [key: string]: string | undefined;\n };\n 'intent-filter'?: ManifestIntentFilter[];\n // ...\n};\n\nexport type ManifestUsesLibrary = {\n $: AndroidManifestAttributes & {\n 'android:required'?: StringBoolean;\n };\n};\n\nexport type ManifestApplication = {\n $: ManifestApplicationAttributes;\n activity?: ManifestActivity[];\n service?: ManifestService[];\n receiver?: ManifestReceiver[];\n 'meta-data'?: ManifestMetaData[];\n 'uses-library'?: ManifestUsesLibrary[];\n // ...\n};\n\ntype ManifestPermission = {\n $: AndroidManifestAttributes & {\n 'android:protectionLevel'?: string | 'signature';\n };\n};\n\nexport type ManifestUsesPermission = {\n $: AndroidManifestAttributes;\n};\n\ntype ManifestUsesFeature = {\n $: AndroidManifestAttributes & {\n 'android:glEsVersion'?: string;\n 'android:required': StringBoolean;\n };\n};\n\nexport type AndroidManifest = {\n manifest: {\n // Probably more, but this is currently all we'd need for most cases in Expo.\n $: {\n 'xmlns:android': string;\n 'xmlns:tools'?: string;\n package?: string;\n [key: string]: string | undefined;\n };\n permission?: ManifestPermission[];\n 'uses-permission'?: ManifestUsesPermission[];\n 'uses-permission-sdk-23'?: ManifestUsesPermission[];\n 'uses-feature'?: ManifestUsesFeature[];\n application?: ManifestApplication[];\n };\n};\n\nexport async function writeAndroidManifestAsync(\n manifestPath: string,\n androidManifest: AndroidManifest\n): Promise<void> {\n const manifestXml = XML.format(androidManifest);\n await fs.ensureDir(path.dirname(manifestPath));\n await fs.writeFile(manifestPath, manifestXml);\n}\n\nexport async function readAndroidManifestAsync(manifestPath: string): Promise<AndroidManifest> {\n const xml = await XML.readXMLAsync({ path: manifestPath });\n if (!isManifest(xml)) {\n throw new Error('Invalid manifest found at: ' + manifestPath);\n }\n return xml;\n}\n\nfunction isManifest(xml: XML.XMLObject): xml is AndroidManifest {\n // TODO: Maybe more validation\n return !!xml.manifest;\n}\n\n/** Returns the `manifest.application` tag ending in `.MainApplication` */\nexport function getMainApplication(androidManifest: AndroidManifest): ManifestApplication | null {\n return (\n androidManifest?.manifest?.application?.filter(e =>\n e?.$?.['android:name'].endsWith('.MainApplication')\n )[0] ?? null\n );\n}\n\nexport function getMainApplicationOrThrow(androidManifest: AndroidManifest): ManifestApplication {\n const mainApplication = getMainApplication(androidManifest);\n assert(mainApplication, 'AndroidManifest.xml is missing the required MainApplication element');\n return mainApplication;\n}\n\nexport function getMainActivityOrThrow(androidManifest: AndroidManifest): ManifestActivity {\n const mainActivity = getMainActivity(androidManifest);\n assert(mainActivity, 'AndroidManifest.xml is missing the required MainActivity element');\n return mainActivity;\n}\n\nexport function getRunnableActivity(androidManifest: AndroidManifest): ManifestActivity | null {\n // Get enabled activities\n const enabledActivities = androidManifest?.manifest?.application?.[0]?.activity?.filter?.(\n (e: any) => e.$['android:enabled'] !== 'false' && e.$['android:enabled'] !== false\n );\n\n if (!enabledActivities) {\n return null;\n }\n\n // Get the activity that has a runnable intent-filter\n for (const activity of enabledActivities) {\n if (Array.isArray(activity['intent-filter'])) {\n for (const intentFilter of activity['intent-filter']) {\n if (\n intentFilter.action?.find(\n action => action.$['android:name'] === 'android.intent.action.MAIN'\n ) &&\n intentFilter.category?.find(\n category => category.$['android:name'] === 'android.intent.category.LAUNCHER'\n )\n ) {\n return activity;\n }\n }\n }\n }\n\n return null;\n}\n\nexport function getMainActivity(androidManifest: AndroidManifest): ManifestActivity | null {\n const mainActivity = androidManifest?.manifest?.application?.[0]?.activity?.filter?.(\n (e: any) => e.$['android:name'] === '.MainActivity'\n );\n return mainActivity?.[0] ?? null;\n}\n\nexport function addMetaDataItemToMainApplication(\n mainApplication: ManifestApplication,\n itemName: string,\n itemValue: string,\n itemType: 'resource' | 'value' = 'value'\n): ManifestApplication {\n let existingMetaDataItem;\n const newItem = {\n $: prefixAndroidKeys({ name: itemName, [itemType]: itemValue }),\n } as ManifestMetaData;\n if (mainApplication['meta-data']) {\n existingMetaDataItem = mainApplication['meta-data'].filter(\n (e: any) => e.$['android:name'] === itemName\n );\n if (existingMetaDataItem.length) {\n existingMetaDataItem[0].$[\n `android:${itemType}` as keyof ManifestMetaDataAttributes\n ] = itemValue;\n } else {\n mainApplication['meta-data'].push(newItem);\n }\n } else {\n mainApplication['meta-data'] = [newItem];\n }\n return mainApplication;\n}\n\nexport function removeMetaDataItemFromMainApplication(mainApplication: any, itemName: string) {\n const index = findMetaDataItem(mainApplication, itemName);\n if (mainApplication?.['meta-data'] && index > -1) {\n mainApplication['meta-data'].splice(index, 1);\n }\n return mainApplication;\n}\n\nfunction findApplicationSubItem(\n mainApplication: ManifestApplication,\n category: keyof ManifestApplication,\n itemName: string\n): number {\n const parent = mainApplication[category];\n if (Array.isArray(parent)) {\n const index = parent.findIndex((e: any) => e.$['android:name'] === itemName);\n\n return index;\n }\n return -1;\n}\n\nexport function findMetaDataItem(mainApplication: any, itemName: string): number {\n return findApplicationSubItem(mainApplication, 'meta-data', itemName);\n}\n\nexport function findUsesLibraryItem(mainApplication: any, itemName: string): number {\n return findApplicationSubItem(mainApplication, 'uses-library', itemName);\n}\n\nexport function getMainApplicationMetaDataValue(\n androidManifest: AndroidManifest,\n name: string\n): string | null {\n const mainApplication = getMainApplication(androidManifest);\n\n if (mainApplication?.hasOwnProperty('meta-data')) {\n const item = mainApplication?.['meta-data']?.find((e: any) => e.$['android:name'] === name);\n return item?.$['android:value'] ?? null;\n }\n\n return null;\n}\n\nexport function addUsesLibraryItemToMainApplication(\n mainApplication: ManifestApplication,\n item: { name: string; required?: boolean }\n): ManifestApplication {\n let existingMetaDataItem;\n const newItem = {\n $: prefixAndroidKeys(item),\n } as ManifestUsesLibrary;\n\n if (mainApplication['uses-library']) {\n existingMetaDataItem = mainApplication['uses-library'].filter(\n e => e.$['android:name'] === item.name\n );\n if (existingMetaDataItem.length) {\n existingMetaDataItem[0].$ = newItem.$;\n } else {\n mainApplication['uses-library'].push(newItem);\n }\n } else {\n mainApplication['uses-library'] = [newItem];\n }\n return mainApplication;\n}\n\nexport function removeUsesLibraryItemFromMainApplication(\n mainApplication: ManifestApplication,\n itemName: string\n) {\n const index = findUsesLibraryItem(mainApplication, itemName);\n if (mainApplication?.['uses-library'] && index > -1) {\n mainApplication['uses-library'].splice(index, 1);\n }\n return mainApplication;\n}\n\nexport function prefixAndroidKeys<T extends Record<string, any> = Record<string, string>>(\n head: T\n): Record<string, any> {\n // prefix all keys with `android:`\n return Object.entries(head).reduce(\n (prev, [key, curr]) => ({ ...prev, [`android:${key}`]: curr }),\n {} as T\n );\n}\n"],"file":"Manifest.js"}
@@ -2,6 +2,8 @@ import { ExpoConfig } from '@expo/config-types';
2
2
  import { ConfigPlugin } from '../Plugin.types';
3
3
  import { AndroidManifest, ManifestUsesPermission } from './Manifest';
4
4
  export declare const withPermissions: ConfigPlugin<string[] | void>;
5
+ export declare const withBlockedPermissions: ConfigPlugin<string[]>;
6
+ export declare function addBlockedPermissions(androidManifest: AndroidManifest, permissions: string[]): AndroidManifest;
5
7
  export declare function getAndroidPermissions(config: Pick<ExpoConfig, 'android'>): string[];
6
8
  export declare function setAndroidPermissions(config: Pick<ExpoConfig, 'android'>, androidManifest: AndroidManifest): AndroidManifest;
7
9
  export declare function isPermissionAlreadyRequested(permission: string, manifestPermissions: ManifestUsesPermission[]): boolean;
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.addBlockedPermissions = addBlockedPermissions;
6
7
  exports.addPermission = addPermission;
7
8
  exports.addPermissionToManifest = addPermissionToManifest;
8
9
  exports.ensurePermission = ensurePermission;
@@ -13,7 +14,17 @@ exports.getPermissions = getPermissions;
13
14
  exports.isPermissionAlreadyRequested = isPermissionAlreadyRequested;
14
15
  exports.removePermissions = removePermissions;
15
16
  exports.setAndroidPermissions = setAndroidPermissions;
16
- exports.withPermissions = void 0;
17
+ exports.withPermissions = exports.withBlockedPermissions = void 0;
18
+
19
+ function _assert() {
20
+ const data = _interopRequireDefault(require("assert"));
21
+
22
+ _assert = function () {
23
+ return data;
24
+ };
25
+
26
+ return data;
27
+ }
17
28
 
18
29
  function _androidPlugins() {
19
30
  const data = require("../plugins/android-plugins");
@@ -25,6 +36,8 @@ function _androidPlugins() {
25
36
  return data;
26
37
  }
27
38
 
39
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
40
+
28
41
  const USES_PERMISSION = 'uses-permission';
29
42
 
30
43
  const withPermissions = (config, permissions) => {
@@ -44,6 +57,78 @@ const withPermissions = (config, permissions) => {
44
57
 
45
58
  exports.withPermissions = withPermissions;
46
59
 
60
+ const withBlockedPermissions = (config, permissions) => {
61
+ var _config$android;
62
+
63
+ (0, _assert().default)(Array.isArray(permissions), 'permissions prop must be an array');
64
+
65
+ if (config !== null && config !== void 0 && (_config$android = config.android) !== null && _config$android !== void 0 && _config$android.permissions && Array.isArray(config.android.permissions)) {
66
+ // Remove any static config permissions
67
+ config.android.permissions = config.android.permissions.filter(permission => !permissions.includes(permission));
68
+ }
69
+
70
+ return (0, _androidPlugins().withAndroidManifest)(config, async config => {
71
+ config.modResults = ensureToolsAvailable(config.modResults);
72
+ config.modResults = addBlockedPermissions(config.modResults, permissions);
73
+ return config;
74
+ });
75
+ };
76
+ /**
77
+ * Ensure the `tools:*` namespace is available in the manifest.
78
+ *
79
+ * @param manifest AndroidManifest.xml
80
+ * @returns manifest with the `tools:*` namespace available
81
+ */
82
+
83
+
84
+ exports.withBlockedPermissions = withBlockedPermissions;
85
+
86
+ function ensureToolsAvailable(manifest) {
87
+ var _manifest$manifest, _manifest$manifest$$;
88
+
89
+ if (manifest !== null && manifest !== void 0 && (_manifest$manifest = manifest.manifest) !== null && _manifest$manifest !== void 0 && (_manifest$manifest$$ = _manifest$manifest.$) !== null && _manifest$manifest$$ !== void 0 && _manifest$manifest$$['xmlns:tools']) {
90
+ return manifest;
91
+ }
92
+
93
+ manifest.manifest.$['xmlns:tools'] = 'http://schemas.android.com/tools';
94
+ return manifest;
95
+ }
96
+
97
+ function addBlockedPermissions(androidManifest, permissions) {
98
+ if (!Array.isArray(androidManifest.manifest['uses-permission'])) {
99
+ androidManifest.manifest['uses-permission'] = [];
100
+ }
101
+
102
+ for (const permission of permissions) {
103
+ androidManifest.manifest['uses-permission'] = ensureBlockedPermission(androidManifest.manifest['uses-permission'], permission);
104
+ }
105
+
106
+ return androidManifest;
107
+ }
108
+ /**
109
+ * Filter any existing permissions matching the provided permission name, then add a
110
+ * restricted permission to overwrite any extra permissions that may be added in a
111
+ * third-party package's AndroidManifest.xml.
112
+ *
113
+ * @param manifestPermissions manifest `uses-permissions` array.
114
+ * @param permission `android:name` of the permission to restrict
115
+ * @returns
116
+ */
117
+
118
+
119
+ function ensureBlockedPermission(manifestPermissions, permission) {
120
+ // Remove permission if it currently exists
121
+ manifestPermissions = manifestPermissions.filter(e => e.$['android:name'] !== permission); // Add a permission with tools:node to overwrite any existing permission and ensure it's removed upon building.
122
+
123
+ manifestPermissions.push({
124
+ $: {
125
+ 'android:name': permission,
126
+ 'tools:node': 'remove'
127
+ }
128
+ });
129
+ return manifestPermissions;
130
+ }
131
+
47
132
  function prefixAndroidPermissionsIfNecessary(permissions) {
48
133
  return permissions.map(permission => {
49
134
  if (!permission.includes('.')) {
@@ -55,9 +140,9 @@ function prefixAndroidPermissionsIfNecessary(permissions) {
55
140
  }
56
141
 
57
142
  function getAndroidPermissions(config) {
58
- var _config$android$permi, _config$android;
143
+ var _config$android$permi, _config$android2;
59
144
 
60
- return (_config$android$permi = (_config$android = config.android) === null || _config$android === void 0 ? void 0 : _config$android.permissions) !== null && _config$android$permi !== void 0 ? _config$android$permi : [];
145
+ return (_config$android$permi = (_config$android2 = config.android) === null || _config$android2 === void 0 ? void 0 : _config$android2.permissions) !== null && _config$android$permi !== void 0 ? _config$android$permi : [];
61
146
  }
62
147
 
63
148
  function setAndroidPermissions(config, androidManifest) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/android/Permissions.ts"],"names":["USES_PERMISSION","withPermissions","config","permissions","Array","isArray","filter","Boolean","android","Set","concat","modResults","setAndroidPermissions","prefixAndroidPermissionsIfNecessary","map","permission","includes","getAndroidPermissions","androidManifest","providedPermissions","permissionsToAdd","manifest","hasOwnProperty","manifestPermissions","forEach","isPermissionAlreadyRequested","addPermissionToManifest","some","e","$","push","removePermissions","permissionNames","targetNames","ensurePermissionNameFormat","nextPermissions","attribute","value","name","addPermission","permissionName","usesPermissions","ensurePermissions","getPermissions","results","targetName","ensurePermission","com","split","pop","toUpperCase","join","permissionObject"],"mappings":"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","sourcesContent":["import { ExpoConfig } from '@expo/config-types';\n\nimport { ConfigPlugin } from '../Plugin.types';\nimport { withAndroidManifest } from '../plugins/android-plugins';\nimport { AndroidManifest, ManifestUsesPermission } from './Manifest';\n\nconst USES_PERMISSION = 'uses-permission';\n\nexport const withPermissions: ConfigPlugin<string[] | void> = (config, permissions) => {\n if (Array.isArray(permissions)) {\n permissions = permissions.filter(Boolean);\n if (!config.android) config.android = {};\n if (!config.android.permissions) config.android.permissions = [];\n config.android.permissions = [\n // @ts-ignore\n ...new Set(config.android.permissions.concat(permissions)),\n ];\n }\n return withAndroidManifest(config, async config => {\n config.modResults = await setAndroidPermissions(config, config.modResults);\n return config;\n });\n};\n\nfunction prefixAndroidPermissionsIfNecessary(permissions: string[]): string[] {\n return permissions.map(permission => {\n if (!permission.includes('.')) {\n return `android.permission.${permission}`;\n }\n return permission;\n });\n}\n\nexport function getAndroidPermissions(config: Pick<ExpoConfig, 'android'>): string[] {\n return config.android?.permissions ?? [];\n}\n\nexport function setAndroidPermissions(\n config: Pick<ExpoConfig, 'android'>,\n androidManifest: AndroidManifest\n) {\n const permissions = getAndroidPermissions(config);\n const providedPermissions = prefixAndroidPermissionsIfNecessary(permissions);\n const permissionsToAdd = [...providedPermissions];\n\n if (!androidManifest.manifest.hasOwnProperty('uses-permission')) {\n androidManifest.manifest['uses-permission'] = [];\n }\n // manifest.manifest['uses-permission'] = [];\n\n const manifestPermissions = androidManifest.manifest['uses-permission'] ?? [];\n\n permissionsToAdd.forEach(permission => {\n if (!isPermissionAlreadyRequested(permission, manifestPermissions)) {\n addPermissionToManifest(permission, manifestPermissions);\n }\n });\n\n return androidManifest;\n}\n\nexport function isPermissionAlreadyRequested(\n permission: string,\n manifestPermissions: ManifestUsesPermission[]\n): boolean {\n return manifestPermissions.some(e => e.$['android:name'] === permission);\n}\n\nexport function addPermissionToManifest(\n permission: string,\n manifestPermissions: ManifestUsesPermission[]\n) {\n manifestPermissions.push({ $: { 'android:name': permission } });\n return manifestPermissions;\n}\n\nexport function removePermissions(androidManifest: AndroidManifest, permissionNames?: string[]) {\n const targetNames = permissionNames ? permissionNames.map(ensurePermissionNameFormat) : null;\n const permissions = androidManifest.manifest[USES_PERMISSION] || [];\n const nextPermissions = [];\n for (const attribute of permissions) {\n if (targetNames) {\n // @ts-ignore: name isn't part of the type\n const value = attribute.$['android:name'] || attribute.$.name;\n if (!targetNames.includes(value)) {\n nextPermissions.push(attribute);\n }\n }\n }\n\n androidManifest.manifest[USES_PERMISSION] = nextPermissions;\n}\n\nexport function addPermission(androidManifest: AndroidManifest, permissionName: string): void {\n const usesPermissions: ManifestUsesPermission[] = androidManifest.manifest[USES_PERMISSION] || [];\n usesPermissions.push({\n $: { 'android:name': permissionName },\n });\n androidManifest.manifest[USES_PERMISSION] = usesPermissions;\n}\n\nexport function ensurePermissions(\n androidManifest: AndroidManifest,\n permissionNames: string[]\n): { [permission: string]: boolean } {\n const permissions = getPermissions(androidManifest);\n\n const results: { [permission: string]: boolean } = {};\n for (const permissionName of permissionNames) {\n const targetName = ensurePermissionNameFormat(permissionName);\n if (!permissions.includes(targetName)) {\n addPermission(androidManifest, targetName);\n results[permissionName] = true;\n } else {\n results[permissionName] = false;\n }\n }\n return results;\n}\n\nexport function ensurePermission(\n androidManifest: AndroidManifest,\n permissionName: string\n): boolean {\n const permissions = getPermissions(androidManifest);\n const targetName = ensurePermissionNameFormat(permissionName);\n\n if (!permissions.includes(targetName)) {\n addPermission(androidManifest, targetName);\n return true;\n }\n return false;\n}\n\nexport function ensurePermissionNameFormat(permissionName: string): string {\n if (permissionName.includes('.')) {\n const com = permissionName.split('.');\n const name = com.pop() as string;\n return [...com, name.toUpperCase()].join('.');\n } else {\n // If shorthand form like `WRITE_CONTACTS` is provided, expand it to `android.permission.WRITE_CONTACTS`.\n return ensurePermissionNameFormat(`android.permission.${permissionName}`);\n }\n}\n\nexport function getPermissions(androidManifest: AndroidManifest): string[] {\n const usesPermissions: { [key: string]: any }[] = androidManifest.manifest[USES_PERMISSION] || [];\n const permissions = usesPermissions.map(permissionObject => {\n return permissionObject.$['android:name'] || permissionObject.$.name;\n });\n return permissions;\n}\n"],"file":"Permissions.js"}
1
+ {"version":3,"sources":["../../src/android/Permissions.ts"],"names":["USES_PERMISSION","withPermissions","config","permissions","Array","isArray","filter","Boolean","android","Set","concat","modResults","setAndroidPermissions","withBlockedPermissions","permission","includes","ensureToolsAvailable","addBlockedPermissions","manifest","$","androidManifest","ensureBlockedPermission","manifestPermissions","e","push","prefixAndroidPermissionsIfNecessary","map","getAndroidPermissions","providedPermissions","permissionsToAdd","hasOwnProperty","forEach","isPermissionAlreadyRequested","addPermissionToManifest","some","removePermissions","permissionNames","targetNames","ensurePermissionNameFormat","nextPermissions","attribute","value","name","addPermission","permissionName","usesPermissions","ensurePermissions","getPermissions","results","targetName","ensurePermission","com","split","pop","toUpperCase","join","permissionObject"],"mappings":"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","sourcesContent":["import { ExpoConfig } from '@expo/config-types';\nimport assert from 'assert';\n\nimport { ConfigPlugin } from '../Plugin.types';\nimport { withAndroidManifest } from '../plugins/android-plugins';\nimport { AndroidManifest, ManifestUsesPermission } from './Manifest';\n\nconst USES_PERMISSION = 'uses-permission';\n\nexport const withPermissions: ConfigPlugin<string[] | void> = (config, permissions) => {\n if (Array.isArray(permissions)) {\n permissions = permissions.filter(Boolean);\n if (!config.android) config.android = {};\n if (!config.android.permissions) config.android.permissions = [];\n config.android.permissions = [\n // @ts-ignore\n ...new Set(config.android.permissions.concat(permissions)),\n ];\n }\n return withAndroidManifest(config, async config => {\n config.modResults = await setAndroidPermissions(config, config.modResults);\n return config;\n });\n};\n\nexport const withBlockedPermissions: ConfigPlugin<string[]> = (config, permissions) => {\n assert(Array.isArray(permissions), 'permissions prop must be an array');\n\n if (config?.android?.permissions && Array.isArray(config.android.permissions)) {\n // Remove any static config permissions\n config.android.permissions = config.android.permissions.filter(\n permission => !permissions.includes(permission)\n );\n }\n\n return withAndroidManifest(config, async config => {\n config.modResults = ensureToolsAvailable(config.modResults);\n config.modResults = addBlockedPermissions(config.modResults, permissions);\n\n return config;\n });\n};\n\n/**\n * Ensure the `tools:*` namespace is available in the manifest.\n *\n * @param manifest AndroidManifest.xml\n * @returns manifest with the `tools:*` namespace available\n */\nfunction ensureToolsAvailable(manifest: AndroidManifest) {\n if (manifest?.manifest?.$?.['xmlns:tools']) {\n return manifest;\n }\n manifest.manifest.$['xmlns:tools'] = 'http://schemas.android.com/tools';\n return manifest;\n}\n\nexport function addBlockedPermissions(androidManifest: AndroidManifest, permissions: string[]) {\n if (!Array.isArray(androidManifest.manifest['uses-permission'])) {\n androidManifest.manifest['uses-permission'] = [];\n }\n\n for (const permission of permissions) {\n androidManifest.manifest['uses-permission'] = ensureBlockedPermission(\n androidManifest.manifest['uses-permission'],\n permission\n );\n }\n\n return androidManifest;\n}\n\n/**\n * Filter any existing permissions matching the provided permission name, then add a\n * restricted permission to overwrite any extra permissions that may be added in a\n * third-party package's AndroidManifest.xml.\n *\n * @param manifestPermissions manifest `uses-permissions` array.\n * @param permission `android:name` of the permission to restrict\n * @returns\n */\nfunction ensureBlockedPermission(\n manifestPermissions: ManifestUsesPermission[],\n permission: string\n) {\n // Remove permission if it currently exists\n manifestPermissions = manifestPermissions.filter(e => e.$['android:name'] !== permission);\n\n // Add a permission with tools:node to overwrite any existing permission and ensure it's removed upon building.\n manifestPermissions.push({\n $: { 'android:name': permission, 'tools:node': 'remove' },\n });\n return manifestPermissions;\n}\n\nfunction prefixAndroidPermissionsIfNecessary(permissions: string[]): string[] {\n return permissions.map(permission => {\n if (!permission.includes('.')) {\n return `android.permission.${permission}`;\n }\n return permission;\n });\n}\n\nexport function getAndroidPermissions(config: Pick<ExpoConfig, 'android'>): string[] {\n return config.android?.permissions ?? [];\n}\n\nexport function setAndroidPermissions(\n config: Pick<ExpoConfig, 'android'>,\n androidManifest: AndroidManifest\n) {\n const permissions = getAndroidPermissions(config);\n const providedPermissions = prefixAndroidPermissionsIfNecessary(permissions);\n const permissionsToAdd = [...providedPermissions];\n\n if (!androidManifest.manifest.hasOwnProperty('uses-permission')) {\n androidManifest.manifest['uses-permission'] = [];\n }\n // manifest.manifest['uses-permission'] = [];\n\n const manifestPermissions = androidManifest.manifest['uses-permission'] ?? [];\n\n permissionsToAdd.forEach(permission => {\n if (!isPermissionAlreadyRequested(permission, manifestPermissions)) {\n addPermissionToManifest(permission, manifestPermissions);\n }\n });\n\n return androidManifest;\n}\n\nexport function isPermissionAlreadyRequested(\n permission: string,\n manifestPermissions: ManifestUsesPermission[]\n): boolean {\n return manifestPermissions.some(e => e.$['android:name'] === permission);\n}\n\nexport function addPermissionToManifest(\n permission: string,\n manifestPermissions: ManifestUsesPermission[]\n) {\n manifestPermissions.push({ $: { 'android:name': permission } });\n return manifestPermissions;\n}\n\nexport function removePermissions(androidManifest: AndroidManifest, permissionNames?: string[]) {\n const targetNames = permissionNames ? permissionNames.map(ensurePermissionNameFormat) : null;\n const permissions = androidManifest.manifest[USES_PERMISSION] || [];\n const nextPermissions = [];\n for (const attribute of permissions) {\n if (targetNames) {\n // @ts-ignore: name isn't part of the type\n const value = attribute.$['android:name'] || attribute.$.name;\n if (!targetNames.includes(value)) {\n nextPermissions.push(attribute);\n }\n }\n }\n\n androidManifest.manifest[USES_PERMISSION] = nextPermissions;\n}\n\nexport function addPermission(androidManifest: AndroidManifest, permissionName: string): void {\n const usesPermissions: ManifestUsesPermission[] = androidManifest.manifest[USES_PERMISSION] || [];\n usesPermissions.push({\n $: { 'android:name': permissionName },\n });\n androidManifest.manifest[USES_PERMISSION] = usesPermissions;\n}\n\nexport function ensurePermissions(\n androidManifest: AndroidManifest,\n permissionNames: string[]\n): { [permission: string]: boolean } {\n const permissions = getPermissions(androidManifest);\n\n const results: { [permission: string]: boolean } = {};\n for (const permissionName of permissionNames) {\n const targetName = ensurePermissionNameFormat(permissionName);\n if (!permissions.includes(targetName)) {\n addPermission(androidManifest, targetName);\n results[permissionName] = true;\n } else {\n results[permissionName] = false;\n }\n }\n return results;\n}\n\nexport function ensurePermission(\n androidManifest: AndroidManifest,\n permissionName: string\n): boolean {\n const permissions = getPermissions(androidManifest);\n const targetName = ensurePermissionNameFormat(permissionName);\n\n if (!permissions.includes(targetName)) {\n addPermission(androidManifest, targetName);\n return true;\n }\n return false;\n}\n\nexport function ensurePermissionNameFormat(permissionName: string): string {\n if (permissionName.includes('.')) {\n const com = permissionName.split('.');\n const name = com.pop() as string;\n return [...com, name.toUpperCase()].join('.');\n } else {\n // If shorthand form like `WRITE_CONTACTS` is provided, expand it to `android.permission.WRITE_CONTACTS`.\n return ensurePermissionNameFormat(`android.permission.${permissionName}`);\n }\n}\n\nexport function getPermissions(androidManifest: AndroidManifest): string[] {\n const usesPermissions: { [key: string]: any }[] = androidManifest.manifest[USES_PERMISSION] || [];\n const permissions = usesPermissions.map(permissionObject => {\n return permissionObject.$['android:name'] || permissionObject.$.name;\n });\n return permissions;\n}\n"],"file":"Permissions.js"}
@@ -17,8 +17,8 @@ export declare const withUpdates: ConfigPlugin<{
17
17
  export declare function getSDKVersion(config: Pick<ExpoConfigUpdates, 'sdkVersion'>): string | null;
18
18
  export declare function getUpdatesEnabled(config: Pick<ExpoConfigUpdates, 'updates'>): boolean;
19
19
  export declare function getUpdatesTimeout(config: Pick<ExpoConfigUpdates, 'updates'>): number;
20
- export declare function getUpdatesCheckOnLaunch(config: Pick<ExpoConfigUpdates, 'updates'>): 'NEVER' | 'ALWAYS';
21
- export declare function setUpdatesConfig(config: ExpoConfigUpdates, androidManifest: AndroidManifest, username: string | null): AndroidManifest;
20
+ export declare function getUpdatesCheckOnLaunch(config: Pick<ExpoConfigUpdates, 'updates'>, expoUpdatesPackageVersion?: string | null): 'NEVER' | 'ERROR_RECOVERY_ONLY' | 'ALWAYS';
21
+ export declare function setUpdatesConfig(config: ExpoConfigUpdates, androidManifest: AndroidManifest, username: string | null, expoUpdatesPackageVersion?: string | null): AndroidManifest;
22
22
  export declare function setVersionsConfig(config: Pick<ExpoConfigUpdates, 'sdkVersion' | 'runtimeVersion'>, androidManifest: AndroidManifest): AndroidManifest;
23
23
  export declare function ensureBuildGradleContainsConfigurationScript(projectRoot: string, buildGradleContents: string): string;
24
24
  export declare function formatApplyLineForBuildGradle(projectRoot: string): string;
@@ -38,6 +38,16 @@ function _resolveFrom() {
38
38
  return data;
39
39
  }
40
40
 
41
+ function _semver() {
42
+ const data = _interopRequireDefault(require("semver"));
43
+
44
+ _semver = function () {
45
+ return data;
46
+ };
47
+
48
+ return data;
49
+ }
50
+
41
51
  function _androidPlugins() {
42
52
  const data = require("../plugins/android-plugins");
43
53
 
@@ -89,7 +99,8 @@ const withUpdates = (config, {
89
99
  expoUsername
90
100
  }) => {
91
101
  return (0, _androidPlugins().withAndroidManifest)(config, config => {
92
- config.modResults = setUpdatesConfig(config, config.modResults, expoUsername);
102
+ const expoUpdatesPackageVersion = (0, _Updates().getExpoUpdatesPackageVersion)(config.modRequest.projectRoot);
103
+ config.modResults = setUpdatesConfig(config, config.modResults, expoUsername, expoUpdatesPackageVersion);
93
104
  return config;
94
105
  });
95
106
  };
@@ -112,10 +123,15 @@ function getUpdatesTimeout(config) {
112
123
  return (_config$updates$fallb = (_config$updates2 = config.updates) === null || _config$updates2 === void 0 ? void 0 : _config$updates2.fallbackToCacheTimeout) !== null && _config$updates$fallb !== void 0 ? _config$updates$fallb : 0;
113
124
  }
114
125
 
115
- function getUpdatesCheckOnLaunch(config) {
126
+ function getUpdatesCheckOnLaunch(config, expoUpdatesPackageVersion) {
116
127
  var _config$updates3, _config$updates4;
117
128
 
118
129
  if (((_config$updates3 = config.updates) === null || _config$updates3 === void 0 ? void 0 : _config$updates3.checkAutomatically) === 'ON_ERROR_RECOVERY') {
130
+ // native 'ERROR_RECOVERY_ONLY' option was only introduced in 0.11.x
131
+ if (expoUpdatesPackageVersion && _semver().default.gte(expoUpdatesPackageVersion, '0.11.0')) {
132
+ return 'ERROR_RECOVERY_ONLY';
133
+ }
134
+
119
135
  return 'NEVER';
120
136
  } else if (((_config$updates4 = config.updates) === null || _config$updates4 === void 0 ? void 0 : _config$updates4.checkAutomatically) === 'ON_LOAD') {
121
137
  return 'ALWAYS';
@@ -124,10 +140,10 @@ function getUpdatesCheckOnLaunch(config) {
124
140
  return 'ALWAYS';
125
141
  }
126
142
 
127
- function setUpdatesConfig(config, androidManifest, username) {
143
+ function setUpdatesConfig(config, androidManifest, username, expoUpdatesPackageVersion) {
128
144
  const mainApplication = (0, _Manifest().getMainApplicationOrThrow)(androidManifest);
129
145
  (0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.ENABLED, String(getUpdatesEnabled(config)));
130
- (0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.CHECK_ON_LAUNCH, getUpdatesCheckOnLaunch(config));
146
+ (0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.CHECK_ON_LAUNCH, getUpdatesCheckOnLaunch(config, expoUpdatesPackageVersion));
131
147
  (0, _Manifest().addMetaDataItemToMainApplication)(mainApplication, Config.LAUNCH_WAIT_MS, String(getUpdatesTimeout(config)));
132
148
  const updateUrl = (0, _Updates().getUpdateUrl)(config, username);
133
149