1"use strict"; 2 3Object.defineProperty(exports, "__esModule", { 4 value: true 5}); 6exports.environmentVariableSerializerPlugin = environmentVariableSerializerPlugin; 7exports.getTransformEnvironment = getTransformEnvironment; 8exports.replaceEnvironmentVariables = replaceEnvironmentVariables; 9function _CountingSet() { 10 const data = _interopRequireDefault(require("metro/src/lib/CountingSet")); 11 _CountingSet = function () { 12 return data; 13 }; 14 return data; 15} 16function _countLines() { 17 const data = _interopRequireDefault(require("metro/src/lib/countLines")); 18 _countLines = function () { 19 return data; 20 }; 21 return data; 22} 23function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 24/** 25 * Copyright © 2022 650 Industries. 26 * 27 * This source code is licensed under the MIT license found in the 28 * LICENSE file in the root directory of this source tree. 29 */ 30 31const debug = require('debug')('expo:metro-config:serializer:env-var'); 32function replaceEnvironmentVariables(code, env) { 33 // match and replace env variables that aren't NODE_ENV or JEST_WORKER_ID 34 // return code.match(/process\.env\.(EXPO_PUBLIC_[A-Z_]+)/g); 35 return code.replace(/process\.env\.([a-zA-Z0-9_]+)/gm, match => { 36 var _env$name; 37 const name = match.replace('process.env.', ''); 38 if ( 39 // Must start with EXPO_PUBLIC_ to be replaced 40 !/^EXPO_PUBLIC_/.test(name)) { 41 return match; 42 } 43 const value = JSON.stringify((_env$name = env[name]) !== null && _env$name !== void 0 ? _env$name : ''); 44 debug(`Inlining environment variable "${match}" with ${value}`); 45 return value; 46 }); 47} 48function getTransformEnvironment(url) { 49 const match = url.match(/[&?]transform\.environment=([^&]+)/); 50 return match ? match[1] : null; 51} 52function getAllExpoPublicEnvVars() { 53 // Create an object containing all environment variables that start with EXPO_PUBLIC_ 54 const env = {}; 55 for (const key in process.env) { 56 if (key.startsWith('EXPO_PUBLIC_')) { 57 // @ts-ignore 58 env[key] = process.env[key]; 59 } 60 } 61 return env; 62} 63function environmentVariableSerializerPlugin(entryPoint, preModules, graph, options) { 64 // Skip replacement in Node.js environments. 65 if (options.sourceUrl && getTransformEnvironment(options.sourceUrl) === 'node') { 66 debug('Skipping environment variable inlining in Node.js environment.'); 67 return [entryPoint, preModules, graph, options]; 68 } 69 70 // Adds about 5ms on a blank Expo Router app. 71 // TODO: We can probably cache the results. 72 73 // In development, we need to add the process.env object to ensure it 74 // persists between Fast Refresh updates. 75 if (options.dev) { 76 // Set the process.env object to the current environment variables object 77 // ensuring they aren't iterable, settable, or enumerable. 78 const str = `process.env=Object.defineProperties(process.env, {${Object.keys(getAllExpoPublicEnvVars()).map(key => `${JSON.stringify(key)}: { value: ${JSON.stringify(process.env[key])} }`).join(',')}});`; 79 const [firstModule, ...restModules] = preModules; 80 // const envCode = `var process=this.process||{};${str}`; 81 // process.env 82 return [entryPoint, [ 83 // First module defines the process.env object. 84 firstModule, 85 // Second module modifies the process.env object. 86 getEnvPrelude(str), 87 // Now we add the rest 88 ...restModules], graph, options]; 89 } 90 91 // In production, inline all process.env variables to ensure they cannot be iterated and read arbitrarily. 92 for (const value of graph.dependencies.values()) { 93 // Skip node_modules, the feature is a bit too sensitive to allow in arbitrary code. 94 if (/node_modules/.test(value.path)) { 95 continue; 96 } 97 for (const index in value.output) { 98 // TODO: This probably breaks source maps. 99 const code = replaceEnvironmentVariables(value.output[index].data.code, process.env); 100 value.output[index].data.code = code; 101 } 102 } 103 return [entryPoint, preModules, graph, options]; 104} 105function getEnvPrelude(contents) { 106 const code = '// HMR env vars from Expo CLI (dev-only)\n' + contents; 107 const name = '__env__'; 108 const lineCount = (0, _countLines().default)(code); 109 return { 110 dependencies: new Map(), 111 getSource: () => Buffer.from(code), 112 inverseDependencies: new (_CountingSet().default)(), 113 path: name, 114 output: [{ 115 type: 'js/script/virtual', 116 data: { 117 code, 118 // @ts-expect-error: typed incorrectly upstream 119 lineCount, 120 map: [] 121 } 122 }] 123 }; 124} 125//# sourceMappingURL=environmentVariableSerializerPlugin.js.map