xref: /expo/packages/@expo/env/build/env.js (revision 033ea1fc)
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4  value: true
5});
6exports.createControlledEnvironment = createControlledEnvironment;
7exports.getFiles = getFiles;
8exports.isEnabled = isEnabled;
9function _chalk() {
10  const data = _interopRequireDefault(require("chalk"));
11  _chalk = function () {
12    return data;
13  };
14  return data;
15}
16function dotenv() {
17  const data = _interopRequireWildcard(require("dotenv"));
18  dotenv = function () {
19    return data;
20  };
21  return data;
22}
23function _dotenvExpand() {
24  const data = require("dotenv-expand");
25  _dotenvExpand = function () {
26    return data;
27  };
28  return data;
29}
30function fs() {
31  const data = _interopRequireWildcard(require("fs"));
32  fs = function () {
33    return data;
34  };
35  return data;
36}
37function _getenv() {
38  const data = require("getenv");
39  _getenv = function () {
40    return data;
41  };
42  return data;
43}
44function path() {
45  const data = _interopRequireWildcard(require("path"));
46  path = function () {
47    return data;
48  };
49  return data;
50}
51function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
52function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
53function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
54/**
55 * Copyright © 2023 650 Industries.
56 *
57 * This source code is licensed under the MIT license found in the
58 * LICENSE file in the root directory of this source tree.
59 */
60
61const debug = require('debug')('expo:env');
62function isEnabled() {
63  return !(0, _getenv().boolish)('EXPO_NO_DOTENV', false);
64}
65function createControlledEnvironment() {
66  const IS_DEBUG = require('debug').enabled('expo:env');
67  let userDefinedEnvironment = undefined;
68  let memo = undefined;
69  function _getForce(projectRoot, options = {}) {
70    if (!isEnabled()) {
71      debug(`Skipping .env files because EXPO_NO_DOTENV is defined`);
72      return {
73        env: {},
74        files: []
75      };
76    }
77    if (!userDefinedEnvironment) {
78      userDefinedEnvironment = {
79        ...process.env
80      };
81    }
82
83    // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
84    const dotenvFiles = getFiles(process.env.NODE_ENV, options);
85    const loadedEnvFiles = [];
86    const parsed = {};
87
88    // Load environment variables from .env* files. Suppress warnings using silent
89    // if this file is missing. dotenv will never modify any environment variables
90    // that have already been set. Variable expansion is supported in .env files.
91    // https://github.com/motdotla/dotenv
92    // https://github.com/motdotla/dotenv-expand
93    dotenvFiles.forEach(dotenvFile => {
94      const absoluteDotenvFile = path().resolve(projectRoot, dotenvFile);
95      if (!fs().existsSync(absoluteDotenvFile)) {
96        return;
97      }
98      try {
99        const results = (0, _dotenvExpand().expand)(dotenv().config({
100          debug: IS_DEBUG,
101          path: absoluteDotenvFile,
102          // We will handle overriding ourselves to allow for HMR.
103          override: true
104        }));
105        if (results.parsed) {
106          loadedEnvFiles.push(absoluteDotenvFile);
107          debug(`Loaded environment variables from: ${absoluteDotenvFile}`);
108          for (const key of Object.keys(results.parsed || {})) {
109            var _userDefinedEnvironme;
110            if (typeof parsed[key] === 'undefined' &&
111            // Custom override logic to prevent overriding variables that
112            // were set before the CLI process began.
113            typeof ((_userDefinedEnvironme = userDefinedEnvironment) === null || _userDefinedEnvironme === void 0 ? void 0 : _userDefinedEnvironme[key]) === 'undefined') {
114              parsed[key] = results.parsed[key];
115            }
116          }
117        } else {
118          debug(`Failed to load environment variables from: ${absoluteDotenvFile}`);
119        }
120      } catch (error) {
121        if (error instanceof Error) {
122          console.error(`Failed to load environment variables from ${absoluteDotenvFile}: ${error.message}`);
123        } else {
124          throw error;
125        }
126      }
127    });
128    if (!loadedEnvFiles.length) {
129      debug(`No environment variables loaded from .env files.`);
130    }
131    return {
132      env: parsed,
133      files: loadedEnvFiles
134    };
135  }
136
137  /** Get the environment variables without mutating the environment. This returns memoized values unless the `force` property is provided. */
138  function get(projectRoot, options = {}) {
139    if (!isEnabled()) {
140      debug(`Skipping .env files because EXPO_NO_DOTENV is defined`);
141      return {
142        env: {},
143        files: []
144      };
145    }
146    if (!options.force && memo) {
147      return memo;
148    }
149    memo = _getForce(projectRoot, options);
150    return memo;
151  }
152
153  /** Load environment variables from .env files and mutate the current `process.env` with the results. */
154  function load(projectRoot, options = {}) {
155    if (!isEnabled()) {
156      debug(`Skipping .env files because EXPO_NO_DOTENV is defined`);
157      return process.env;
158    }
159    const envInfo = get(projectRoot, options);
160    if (!options.force) {
161      const keys = Object.keys(envInfo.env);
162      if (keys.length) {
163        console.log(_chalk().default.gray('env: load', envInfo.files.map(file => path().basename(file)).join(' ')));
164        console.log(_chalk().default.gray('env: export', keys.join(' ')));
165      }
166    }
167    process.env = {
168      ...process.env,
169      ...envInfo.env
170    };
171    return process.env;
172  }
173  return {
174    load,
175    get,
176    _getForce
177  };
178}
179function getFiles(mode, {
180  silent = false
181} = {}) {
182  if (!isEnabled()) {
183    debug(`Skipping .env files because EXPO_NO_DOTENV is defined`);
184    return [];
185  }
186  if (!mode) {
187    if (silent) {
188      debug('NODE_ENV is not defined, proceeding without mode-specific .env');
189    } else {
190      console.error(_chalk().default.red('The NODE_ENV environment variable is required but was not specified. Ensure the project is bundled with Expo CLI or NODE_ENV is set.'));
191      console.error(_chalk().default.red('Proceeding without mode-specific .env'));
192    }
193  }
194  if (mode && !['development', 'test', 'production'].includes(mode)) {
195    throw new Error(`Environment variable "NODE_ENV=${mode}" is invalid. Valid values are "development", "test", and "production`);
196  }
197  if (!mode) {
198    // Support environments that don't respect NODE_ENV
199    return [`.env.local`, '.env'];
200  }
201  // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
202  const dotenvFiles = [`.env.${mode}.local`,
203  // Don't include `.env.local` for `test` environment
204  // since normally you expect tests to produce the same
205  // results for everyone
206  mode !== 'test' && `.env.local`, `.env.${mode}`, '.env'].filter(Boolean);
207  return dotenvFiles;
208}
209//# sourceMappingURL=env.js.map