xref: /expo/packages/@expo/env/build/env.js (revision 7c8f952f)
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 memoEnvironment = undefined;
69  function _getForce(projectRoot, options = {}) {
70    if (!isEnabled()) {
71      debug(`Skipping .env files because EXPO_NO_DOTENV is defined`);
72      return {};
73    }
74    if (!userDefinedEnvironment) {
75      userDefinedEnvironment = {
76        ...process.env
77      };
78    }
79
80    // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
81    const dotenvFiles = getFiles(process.env.NODE_ENV, options);
82    const loadedEnvFiles = [];
83    const parsed = {};
84
85    // Load environment variables from .env* files. Suppress warnings using silent
86    // if this file is missing. dotenv will never modify any environment variables
87    // that have already been set. Variable expansion is supported in .env files.
88    // https://github.com/motdotla/dotenv
89    // https://github.com/motdotla/dotenv-expand
90    dotenvFiles.forEach(dotenvFile => {
91      const absoluteDotenvFile = path().resolve(projectRoot, dotenvFile);
92      if (!fs().existsSync(absoluteDotenvFile)) {
93        return;
94      }
95      try {
96        const results = (0, _dotenvExpand().expand)(dotenv().config({
97          debug: IS_DEBUG,
98          path: absoluteDotenvFile,
99          // We will handle overriding ourselves to allow for HMR.
100          override: true
101        }));
102        if (results.parsed) {
103          loadedEnvFiles.push(absoluteDotenvFile);
104          debug(`Loaded environment variables from: ${absoluteDotenvFile}`);
105          for (const key of Object.keys(results.parsed || {})) {
106            var _userDefinedEnvironme;
107            if (typeof parsed[key] === 'undefined' &&
108            // Custom override logic to prevent overriding variables that
109            // were set before the CLI process began.
110            typeof ((_userDefinedEnvironme = userDefinedEnvironment) === null || _userDefinedEnvironme === void 0 ? void 0 : _userDefinedEnvironme[key]) === 'undefined') {
111              parsed[key] = results.parsed[key];
112            }
113          }
114        } else {
115          debug(`Failed to load environment variables from: ${absoluteDotenvFile}`);
116        }
117      } catch (error) {
118        if (error instanceof Error) {
119          console.error(`Failed to load environment variables from ${absoluteDotenvFile}: ${error.message}`);
120        } else {
121          throw error;
122        }
123      }
124    });
125    if (!loadedEnvFiles.length) {
126      debug(`No environment variables loaded from .env files.`);
127    }
128    return parsed;
129  }
130
131  /** Get the environment variables without mutating the environment. This returns memoized values unless the `force` property is provided. */
132  function get(projectRoot, options = {}) {
133    if (!isEnabled()) {
134      debug(`Skipping .env files because EXPO_NO_DOTENV is defined`);
135      return {};
136    }
137    if (!options.force && memoEnvironment) {
138      return memoEnvironment;
139    }
140    memoEnvironment = _getForce(projectRoot, options);
141    return memoEnvironment;
142  }
143
144  /** Load environment variables from .env files and mutate the current `process.env` with the results. */
145  function load(projectRoot, options = {}) {
146    if (!isEnabled()) {
147      debug(`Skipping .env files because EXPO_NO_DOTENV is defined`);
148      return process.env;
149    }
150    const env = get(projectRoot, options);
151    process.env = {
152      ...process.env,
153      ...env
154    };
155    return process.env;
156  }
157  return {
158    load,
159    get,
160    _getForce
161  };
162}
163function getFiles(mode, {
164  silent = false
165} = {}) {
166  if (!isEnabled()) {
167    debug(`Skipping .env files because EXPO_NO_DOTENV is defined`);
168    return [];
169  }
170  if (!mode) {
171    if (silent) {
172      debug('NODE_ENV is not defined, proceeding without mode-specific .env');
173    } else {
174      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.'));
175      console.error(_chalk().default.red('Proceeding without mode-specific .env'));
176    }
177  }
178  if (mode && !['development', 'test', 'production'].includes(mode)) {
179    throw new Error(`Environment variable "NODE_ENV=${mode}" is invalid. Valid values are "development", "test", and "production`);
180  }
181  if (!mode) {
182    // Support environments that don't respect NODE_ENV
183    return [`.env.local`, '.env'];
184  }
185  // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
186  const dotenvFiles = [`.env.${mode}.local`,
187  // Don't include `.env.local` for `test` environment
188  // since normally you expect tests to produce the same
189  // results for everyone
190  mode !== 'test' && `.env.local`, `.env.${mode}`, '.env'].filter(Boolean);
191  return dotenvFiles;
192}
193//# sourceMappingURL=env.js.map