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