Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-native-dotenv

Package Overview
Dependencies
Maintainers
3
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-native-dotenv - npm Package Compare versions

Comparing version 3.3.1 to 3.4.0

__tests__/__fixtures__/default-safe/.babelrc

7

__tests__/index.test.js

@@ -56,2 +56,9 @@ const {transformFileSync} = require('@babel/core')

it('should prioritize environment variables over variables defined in .env even when safe', () => {
process.env.API_KEY = 'i win'
const {code} = transformFileSync(FIXTURES + 'default-safe/source.js')
expect(code).toBe('console.log("i win");\nconsole.log("username");')
})
it('should load custom env file', () => {

@@ -58,0 +65,0 @@ const {code} = transformFileSync(FIXTURES + 'filename/source.js')

1

.github/pull_request_template.md

@@ -8,1 +8,2 @@ ## Link to issue ##

* What was the solution to the problem?
* Did you set option `verbose: true` in your babel config? If so, what was the output?

265

index.js

@@ -1,2 +0,2 @@

const {readFileSync} = require('fs')
const {readFileSync, statSync} = require('fs')
const dotenv = require('dotenv')

@@ -21,108 +21,195 @@

module.exports = ({types: t}) => ({
name: 'dotenv-import',
pre() {
this.opts = {
envName: 'APP_ENV',
moduleName: '@env',
path: '.env',
whitelist: null,
blacklist: null,
allowlist: null,
blocklist: null,
safe: false,
allowUndefined: true,
verbose: false,
...this.opts,
function safeObjectAssign(targetObject, sourceObject, exceptions = []) {
const keys = Object.keys(targetObject)
for (let i = 0, length = keys.length; i < length; i++) {
if (targetObject[keys[i]] && sourceObject[keys[i]]) {
targetObject[keys[i]] = sourceObject[keys[i]]
}
}
const babelMode = process.env[this.opts.envName] || (process.env.BABEL_ENV && process.env.BABEL_ENV !== 'undefined' && process.env.BABEL_ENV !== 'development' && process.env.BABEL_ENV) || process.env.NODE_ENV || 'development'
if (this.opts.verbose) {
console.log('dotenvMode', babelMode)
for (let j = 0, length = exceptions.length; j < length; j++) {
if (sourceObject[exceptions[j]]) {
targetObject[exceptions[j]] = sourceObject[exceptions[j]]
}
}
if (this.opts.safe) {
const parsed = parseDotenvFile(this.opts.path, this.opts.verbose)
const localParsed = parseDotenvFile(this.opts.path + '.local')
const modeParsed = parseDotenvFile(this.opts.path + '.' + babelMode)
const modeLocalParsed = parseDotenvFile(this.opts.path + '.' + babelMode + '.local')
this.env = Object.assign(Object.assign(Object.assign(parsed, modeParsed), localParsed), modeLocalParsed)
this.env.NODE_ENV = process.env.NODE_ENV || babelMode
} else {
dotenv.config({
path: this.opts.path + '.' + babelMode + '.local',
silent: true,
})
dotenv.config({
path: this.opts.path + '.' + babelMode,
silent: true,
})
dotenv.config({
path: this.opts.path + '.local',
silent: true,
})
dotenv.config({
path: this.opts.path,
})
this.env = process.env
}
},
return targetObject
}
visitor: {
ImportDeclaration(path, {opts}) {
if (path.node.source.value === opts.moduleName) {
for (const [idx, specifier] of path.node.specifiers.entries()) {
if (specifier.type === 'ImportDefaultSpecifier') {
throw path.get('specifiers')[idx].buildCodeFrameError('Default import is not supported')
}
function mtime(filePath) {
try {
return statSync(filePath).mtimeMs
} catch {
return null
}
}
if (specifier.type === 'ImportNamespaceSpecifier') {
throw path.get('specifiers')[idx].buildCodeFrameError('Wildcard import is not supported')
}
module.exports = (api, options) => {
const t = api.types
this.env = {}
options = {
envName: 'APP_ENV',
moduleName: '@env',
path: '.env',
whitelist: null,
blacklist: null,
allowlist: null,
blocklist: null,
safe: false,
allowUndefined: true,
verbose: false,
...options,
}
const babelMode = process.env[options.envName] || (process.env.BABEL_ENV && process.env.BABEL_ENV !== 'undefined' && process.env.BABEL_ENV !== 'development' && process.env.BABEL_ENV) || process.env.NODE_ENV || 'development'
const localFilePath = options.path + '.local'
const modeFilePath = options.path + '.' + babelMode
const modeLocalFilePath = options.path + '.' + babelMode + '.local'
if (specifier.imported && specifier.local) {
const importedId = specifier.imported.name
const localId = specifier.local.name
if (options.verbose) {
console.log('dotenvMode', babelMode)
}
if (Array.isArray(opts.allowlist) && !opts.allowlist.includes(importedId)) {
throw path.get('specifiers')[idx].buildCodeFrameError(`"${importedId}" was not present in allowlist`)
} else if (Array.isArray(opts.whitelist) && !opts.whitelist.includes(importedId)) {
console.warn('[DEPRECATION WARNING] This option is will be deprecated soon. Use allowlist instead')
throw path.get('specifiers')[idx].buildCodeFrameError(`"${importedId}" was not whitelisted`)
}
api.cache.using(() => mtime(options.path))
api.cache.using(() => mtime(localFilePath))
api.cache.using(() => mtime(modeFilePath))
api.cache.using(() => mtime(modeLocalFilePath))
if (Array.isArray(opts.blocklist) && opts.blocklist.includes(importedId)) {
throw path.get('specifiers')[idx].buildCodeFrameError(`"${importedId}" was not present in blocklist`)
} else if (Array.isArray(opts.blacklist) && opts.blacklist.includes(importedId)) {
console.warn('[DEPRECATION WARNING] This option is will be deprecated soon. Use blocklist instead')
throw path.get('specifiers')[idx].buildCodeFrameError(`"${importedId}" was blacklisted`)
const dotenvTemporary = Object.assign({}, process.env)
if (options.safe) {
const parsed = parseDotenvFile(options.path, options.verbose)
const localParsed = parseDotenvFile(localFilePath, options.verbose)
const modeParsed = parseDotenvFile(modeFilePath, options.verbose)
const modeLocalParsed = parseDotenvFile(modeLocalFilePath, options.verbose)
this.env = safeObjectAssign(Object.assign(Object.assign(Object.assign(parsed, modeParsed), localParsed), modeLocalParsed), dotenvTemporary, ['NODE_ENV', 'BABEL_ENV', options.envName])
this.env.NODE_ENV = process.env.NODE_ENV || babelMode
} else {
dotenv.config({
path: modeLocalFilePath,
silent: true,
})
dotenv.config({
path: modeFilePath,
silent: true,
})
dotenv.config({
path: localFilePath,
silent: true,
})
dotenv.config({
path: options.path,
})
this.env = process.env
this.env = Object.assign(this.env, dotenvTemporary)
}
api.addExternalDependency(options.path)
api.addExternalDependency(localFilePath)
api.addExternalDependency(modeFilePath)
api.addExternalDependency(modeLocalFilePath)
return ({
name: 'dotenv-import',
pre() {
this.opts = {
envName: 'APP_ENV',
moduleName: '@env',
path: '.env',
whitelist: null,
blacklist: null,
allowlist: null,
blocklist: null,
safe: false,
allowUndefined: true,
verbose: false,
...this.opts,
}
const dotenvTemporary = Object.assign({}, process.env)
if (this.opts.safe) {
const parsed = parseDotenvFile(this.opts.path, this.opts.verbose)
const localParsed = parseDotenvFile(localFilePath)
const modeParsed = parseDotenvFile(modeFilePath)
const modeLocalParsed = parseDotenvFile(modeLocalFilePath)
this.env = safeObjectAssign(Object.assign(Object.assign(Object.assign(parsed, modeParsed), localParsed), modeLocalParsed), dotenvTemporary, ['NODE_ENV', 'BABEL_ENV', options.envName])
this.env.NODE_ENV = process.env.NODE_ENV || babelMode
} else {
dotenv.config({
path: modeLocalFilePath,
silent: true,
})
dotenv.config({
path: modeFilePath,
silent: true,
})
dotenv.config({
path: localFilePath,
silent: true,
})
dotenv.config({
path: options.path,
})
this.env = process.env
this.env = Object.assign(this.env, dotenvTemporary)
}
},
visitor: {
ImportDeclaration(path, {opts}) {
if (path.node.source.value === opts.moduleName) {
for (const [idx, specifier] of path.node.specifiers.entries()) {
if (specifier.type === 'ImportDefaultSpecifier') {
throw path.get('specifiers')[idx].buildCodeFrameError('Default import is not supported')
}
if (!opts.allowUndefined && !Object.prototype.hasOwnProperty.call(this.env, importedId)) {
throw path.get('specifiers')[idx].buildCodeFrameError(`"${importedId}" is not defined in ${opts.path}`)
if (specifier.type === 'ImportNamespaceSpecifier') {
throw path.get('specifiers')[idx].buildCodeFrameError('Wildcard import is not supported')
}
const binding = path.scope.getBinding(localId)
for (const refPath of binding.referencePaths) {
refPath.replaceWith(t.valueToNode(this.env[importedId]))
if (specifier.imported && specifier.local) {
const importedId = specifier.imported.name
const localId = specifier.local.name
if (Array.isArray(opts.allowlist) && !opts.allowlist.includes(importedId)) {
throw path.get('specifiers')[idx].buildCodeFrameError(`"${importedId}" was not present in allowlist`)
} else if (Array.isArray(opts.whitelist) && !opts.whitelist.includes(importedId)) {
console.warn('[DEPRECATION WARNING] This option is will be deprecated soon. Use allowlist instead')
throw path.get('specifiers')[idx].buildCodeFrameError(`"${importedId}" was not whitelisted`)
}
if (Array.isArray(opts.blocklist) && opts.blocklist.includes(importedId)) {
throw path.get('specifiers')[idx].buildCodeFrameError(`"${importedId}" was not present in blocklist`)
} else if (Array.isArray(opts.blacklist) && opts.blacklist.includes(importedId)) {
console.warn('[DEPRECATION WARNING] This option is will be deprecated soon. Use blocklist instead')
throw path.get('specifiers')[idx].buildCodeFrameError(`"${importedId}" was blacklisted`)
}
if (!opts.allowUndefined && !Object.prototype.hasOwnProperty.call(this.env, importedId)) {
throw path.get('specifiers')[idx].buildCodeFrameError(`"${importedId}" is not defined in ${opts.path}`)
}
const binding = path.scope.getBinding(localId)
for (const refPath of binding.referencePaths) {
refPath.replaceWith(t.valueToNode(this.env[importedId]))
}
}
}
path.remove()
}
},
MemberExpression(path, {opts}) {
if (path.get('object').matchesPattern('process.env')) {
const key = path.toComputedKey()
if (t.isStringLiteral(key)) {
const importedId = key.value
const value = (opts.env && importedId in opts.env) ? opts.env[importedId] : process.env[importedId]
path.remove()
}
},
MemberExpression(path, {opts}) {
if (path.get('object').matchesPattern('process.env')) {
const key = path.toComputedKey()
if (t.isStringLiteral(key)) {
const importedId = key.value
const value = (opts.env && importedId in opts.env) ? opts.env[importedId] : process.env[importedId]
path.replaceWith(t.valueToNode(value))
path.replaceWith(t.valueToNode(value))
}
}
}
},
},
},
})
})
}
{
"name": "react-native-dotenv",
"version": "3.3.1",
"version": "3.4.0",
"description": "Load environment variables using import statements.",

@@ -26,10 +26,10 @@ "repository": "github:goatandsheep/react-native-dotenv",

"dependencies": {
"dotenv": "^10.0.0"
"dotenv": "^16.0.0"
},
"devDependencies": {
"@babel/core": "7.16.0",
"@babel/core": "7.17.7",
"codecov": "^3.8.3",
"jest": "27.4.4",
"jest": "27.5.1",
"jest-junit": "^13.0.0",
"xo": "^0.47.0"
"xo": "^0.48.0"
},

@@ -36,0 +36,0 @@ "author": "Kemal Ahmed",

@@ -6,3 +6,3 @@ # react-native-dotenv [![CircleCI](https://circleci.com/gh/goatandsheep/react-native-dotenv.svg?style=svg)](https://circleci.com/gh/goatandsheep/react-native-dotenv)

[![npm version](https://badgen.net/npm/v/react-native-dotenv)](https://www.npmjs.com/package/react-native-dotenv)
[![dependencies Status](https://badgen.net/david/dep/goatandsheep/react-native-dotenv)](https://david-dm.org/goatandsheep/react-native-dotenv)
[![dependencies Status](https://img.shields.io/librariesio/release/npm/react-native-dotenv)](https://img.shields.io/librariesio/release/npm/react-native-dotenv)
[![codecov](https://badgen.net/codecov/c/github/goatandsheep/react-native-dotenv)](https://codecov.io/gh/goatandsheep/react-native-dotenv)

@@ -295,2 +295,6 @@ [![XO code style](https://badgen.net/badge/code%20style/XO/cyan)](https://github.com/xojs/xo) [![Join the chat at https://gitter.im/pass-it-on/react-native-dotenv](https://badges.gitter.im/pass-it-on/react-native-dotenv.svg)](https://gitter.im/pass-it-on/react-native-dotenv?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

and
`expo start --clear`
or

@@ -300,2 +304,6 @@

You can also set `api.cache(false)` in your babel config
metro.config.js`resetCache: true`
Maybe a solution for updating package.json scripts:

@@ -302,0 +310,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc