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