with-release-no-internet.js raw

   1  /**
   2   * Strip android.permission.INTERNET from release builds only.
   3   *
   4   * The main AndroidManifest keeps the permission so debug builds can talk
   5   * to Metro (and any other dev-time HTTP endpoint). Android's manifest
   6   * merger applies build-type overlays AFTER the main manifest, so dropping
   7   * a `src/release/AndroidManifest.xml` with `tools:node="remove"` is exactly
   8   * the right level of surgery — debug and release diverge cleanly with no
   9   * conditional logic at app.json level.
  10   *
  11   * Wired into app.json via:
  12   *   "plugins": [ ..., "./plugins/with-release-no-internet" ]
  13   */
  14  const { withDangerousMod } = require('@expo/config-plugins');
  15  const fs = require('fs');
  16  const path = require('path');
  17  
  18  const RELEASE_MANIFEST = `<?xml version="1.0" encoding="utf-8"?>
  19  <manifest
  20      xmlns:android="http://schemas.android.com/apk/res/android"
  21      xmlns:tools="http://schemas.android.com/tools">
  22    <!-- The app is a pure URL router. Release builds make no network
  23         calls themselves; debug builds keep INTERNET so Metro can reach them.
  24         Written by plugins/with-release-no-internet.js — do not edit by hand;
  25         this file is regenerated on every expo prebuild. -->
  26    <uses-permission android:name="android.permission.INTERNET" tools:node="remove"/>
  27  </manifest>
  28  `;
  29  
  30  module.exports = function withReleaseNoInternet(config) {
  31    return withDangerousMod(config, [
  32      'android',
  33      async (config) => {
  34        const dir = path.join(
  35          config.modRequest.platformProjectRoot,
  36          'app/src/release',
  37        );
  38        fs.mkdirSync(dir, { recursive: true });
  39        fs.writeFileSync(path.join(dir, 'AndroidManifest.xml'), RELEASE_MANIFEST);
  40        return config;
  41      },
  42    ]);
  43  };
  44