1{"version":3,"file":"environmentVariableSerializerPlugin.js","names":["_countLines","data","_interopRequireDefault","require","obj","__esModule","default","debug","replaceEnvironmentVariables","code","env","replace","match","_env$name","name","test","value","JSON","stringify","getTransformEnvironment","url","getAllExpoPublicEnvVars","key","process","startsWith","environmentVariableSerializerPlugin","entryPoint","preModules","graph","options","sourceUrl","dev","str","Object","keys","map","join","firstModule","restModules","getEnvPrelude","dependencies","values","path","index","output","contents","Map","getSource","Buffer","from","inverseDependencies","Set","type","lineCount","countLines"],"sources":["../../src/serializer/environmentVariableSerializerPlugin.ts"],"sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport { Graph, MixedOutput, Module, SerializerOptions } from 'metro';\nimport countLines from 'metro/src/lib/countLines';\n\nimport { SerializerParameters } from './withExpoSerializers';\n\nconst debug = require('debug')('expo:metro-config:serializer:env-var') as typeof console.log;\n\nexport function replaceEnvironmentVariables(\n  code: string,\n  env: Record<string, string | undefined>\n): string {\n  // match and replace env variables that aren't NODE_ENV or JEST_WORKER_ID\n  // return code.match(/process\\.env\\.(EXPO_PUBLIC_[A-Z_]+)/g);\n  return code.replace(/process\\.env\\.([a-zA-Z0-9_]+)/gm, (match) => {\n    const name = match.replace('process.env.', '');\n    if (\n      // Must start with EXPO_PUBLIC_ to be replaced\n      !/^EXPO_PUBLIC_/.test(name)\n    ) {\n      return match;\n    }\n\n    const value = JSON.stringify(env[name] ?? '');\n    debug(`Inlining environment variable \"${match}\" with ${value}`);\n    return value;\n  });\n}\n\nexport function getTransformEnvironment(url: string): string | null {\n  const match = url.match(/[&?]transform\\.environment=([^&]+)/);\n  return match ? match[1] : null;\n}\n\nfunction getAllExpoPublicEnvVars() {\n  // Create an object containing all environment variables that start with EXPO_PUBLIC_\n  const env = {};\n  for (const key in process.env) {\n    if (key.startsWith('EXPO_PUBLIC_')) {\n      // @ts-ignore\n      env[key] = process.env[key];\n    }\n  }\n  return env;\n}\n\nexport function environmentVariableSerializerPlugin(\n  entryPoint: string,\n  preModules: readonly Module[],\n  graph: Graph,\n  options: SerializerOptions\n): SerializerParameters {\n  // Skip replacement in Node.js environments.\n  if (options.sourceUrl && getTransformEnvironment(options.sourceUrl) === 'node') {\n    debug('Skipping environment variable inlining in Node.js environment.');\n    return [entryPoint, preModules, graph, options];\n  }\n\n  // Adds about 5ms on a blank Expo Router app.\n  // TODO: We can probably cache the results.\n\n  // In development, we need to add the process.env object to ensure it\n  // persists between Fast Refresh updates.\n  if (options.dev) {\n    // Set the process.env object to the current environment variables object\n    // ensuring they aren't iterable, settable, or enumerable.\n    const str = `process.env=Object.defineProperties(process.env, {${Object.keys(\n      getAllExpoPublicEnvVars()\n    )\n      .map((key) => `${JSON.stringify(key)}: { value: ${JSON.stringify(process.env[key])} }`)\n      .join(',')}});`;\n\n    const [firstModule, ...restModules] = preModules;\n    // const envCode = `var process=this.process||{};${str}`;\n    // process.env\n    return [\n      entryPoint,\n      [\n        // First module defines the process.env object.\n        firstModule,\n        // Second module modifies the process.env object.\n        getEnvPrelude(str),\n        // Now we add the rest\n        ...restModules,\n      ],\n      graph,\n      options,\n    ];\n  }\n\n  // In production, inline all process.env variables to ensure they cannot be iterated and read arbitrarily.\n  for (const value of graph.dependencies.values()) {\n    // Skip node_modules, the feature is a bit too sensitive to allow in arbitrary code.\n    if (/node_modules/.test(value.path)) {\n      continue;\n    }\n\n    for (const index in value.output) {\n      // TODO: This probably breaks source maps.\n      const code = replaceEnvironmentVariables(value.output[index].data.code, process.env);\n      value.output[index].data.code = code;\n    }\n  }\n  return [entryPoint, preModules, graph, options];\n}\n\nfunction getEnvPrelude(contents: string): Module<MixedOutput> {\n  const code = '// HMR env vars from Expo CLI (dev-only)\\n' + contents;\n  const name = '__env__';\n\n  return {\n    dependencies: new Map(),\n    getSource: (): Buffer => Buffer.from(code),\n    inverseDependencies: new Set(),\n    path: name,\n    output: [\n      {\n        type: 'js/script/virtual',\n        data: {\n          code,\n          lineCount: countLines(code),\n          map: [],\n        },\n      },\n    ],\n  };\n}\n"],"mappings":"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"}