diff --git a/client/components/Nav.jsx b/client/components/Nav.jsx
index 22305b3a..dd7c800e 100644
--- a/client/components/Nav.jsx
+++ b/client/components/Nav.jsx
@@ -10,14 +10,13 @@ import * as projectActions from '../modules/IDE/actions/project';
import { setAllAccessibleOutput } from '../modules/IDE/actions/preferences';
import { logoutUser } from '../modules/User/actions';
+import getConfig from '../utils/getConfig';
import { metaKeyName, } from '../utils/metaKey';
import CaretLeftIcon from '../images/left-arrow.svg';
import TriangleIcon from '../images/down-filled-triangle.svg';
import LogoIcon from '../images/p5js-logo-small.svg';
-const __process = (typeof global !== 'undefined' ? global : window).process;
-
class Nav extends React.PureComponent {
constructor(props) {
super(props);
@@ -272,7 +271,7 @@ class Nav extends React.PureComponent {
New
- { __process.env.LOGIN_ENABLED && (!this.props.project.owner || this.isUserOwner()) &&
+ { getConfig('LOGIN_ENABLED') && (!this.props.project.owner || this.isUserOwner()) &&
}
- {__process.env.UI_COLLECTIONS_ENABLED &&
+ {getConfig('UI_COLLECTIONS_ENABLED') &&
this.props.user.authenticated &&
this.props.project.id &&
@@ -337,7 +336,7 @@ class Nav extends React.PureComponent {
Add to Collection
}
- { __process.env.EXAMPLES_ENABLED &&
+ { getConfig('EXAMPLES_ENABLED') &&
- {__process.env.UI_COLLECTIONS_ENABLED &&
+ {getConfig('UI_COLLECTIONS_ENABLED') &&
- {this.state.isMounted && !window.devToolsExtension && __process.env.NODE_ENV === 'development' && }
+ {this.state.isMounted && !window.devToolsExtension && getConfig('NODE_ENV') === 'development' && }
{this.props.children}
);
diff --git a/client/modules/IDE/actions/uploader.js b/client/modules/IDE/actions/uploader.js
index c7a0139f..c3518630 100644
--- a/client/modules/IDE/actions/uploader.js
+++ b/client/modules/IDE/actions/uploader.js
@@ -1,10 +1,11 @@
import axios from 'axios';
+import getConfig from '../../../utils/getConfig';
import { createFile } from './files';
import { TEXT_FILE_REGEX } from '../../../../server/utils/fileUtils';
const __process = (typeof global !== 'undefined' ? global : window).process;
-const s3BucketHttps = __process.env.S3_BUCKET_URL_BASE ||
- `https://s3-${__process.env.AWS_REGION}.amazonaws.com/${__process.env.S3_BUCKET}/`;
+const s3BucketHttps = getConfig('S3_BUCKET_URL_BASE') ||
+ `https://s3-${getConfig('AWS_REGION')}.amazonaws.com/${getConfig('S3_BUCKET')}/`;
const ROOT_URL = __process.env.API_URL;
const MAX_LOCAL_FILE_SIZE = 80000; // bytes, aka 80 KB
diff --git a/client/modules/IDE/components/AssetSize.jsx b/client/modules/IDE/components/AssetSize.jsx
index 2e4c1282..cf2356e2 100644
--- a/client/modules/IDE/components/AssetSize.jsx
+++ b/client/modules/IDE/components/AssetSize.jsx
@@ -3,8 +3,9 @@ import React from 'react';
import { connect } from 'react-redux';
import prettyBytes from 'pretty-bytes';
-const __process = (typeof global !== 'undefined' ? global : window).process;
-const limit = __process.env.UPLOAD_LIMIT || 250000000;
+import getConfig from '../../../utils/getConfig';
+
+const limit = getConfig('UPLOAD_LIMIT') || 250000000;
const MAX_SIZE_B = limit;
const formatPercent = (percent) => {
diff --git a/client/modules/IDE/components/FileUploader.jsx b/client/modules/IDE/components/FileUploader.jsx
index c9515f5c..e2e6e509 100644
--- a/client/modules/IDE/components/FileUploader.jsx
+++ b/client/modules/IDE/components/FileUploader.jsx
@@ -4,11 +4,11 @@ import Dropzone from 'dropzone';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as UploaderActions from '../actions/uploader';
+import getConfig from '../../../utils/getConfig';
import { fileExtensionsAndMimeTypes } from '../../../../server/utils/fileUtils';
-const __process = (typeof global !== 'undefined' ? global : window).process;
-const s3Bucket = __process.env.S3_BUCKET_URL_BASE ||
- `https://s3-${__process.env.AWS_REGION}.amazonaws.com/${__process.env.S3_BUCKET}/`;
+const s3Bucket = getConfig('S3_BUCKET_URL_BASE') ||
+ `https://s3-${getConfig('AWS_REGION')}.amazonaws.com/${getConfig('S3_BUCKET')}/`;
class FileUploader extends React.Component {
componentDidMount() {
diff --git a/client/modules/IDE/components/UploadFileModal.jsx b/client/modules/IDE/components/UploadFileModal.jsx
index 27fa7c6f..ff7e9c2d 100644
--- a/client/modules/IDE/components/UploadFileModal.jsx
+++ b/client/modules/IDE/components/UploadFileModal.jsx
@@ -3,12 +3,12 @@ import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import prettyBytes from 'pretty-bytes';
+import getConfig from '../../../utils/getConfig';
import FileUploader from './FileUploader';
import { getreachedTotalSizeLimit } from '../selectors/users';
import ExitIcon from '../../../images/exit.svg';
-const __process = (typeof global !== 'undefined' ? global : window).process;
-const limit = __process.env.UPLOAD_LIMIT || 250000000;
+const limit = getConfig('UPLOAD_LIMIT') || 250000000;
const limitText = prettyBytes(limit);
class UploadFileModal extends React.Component {
diff --git a/client/modules/IDE/selectors/users.js b/client/modules/IDE/selectors/users.js
index 556d99dd..eabf2e5c 100644
--- a/client/modules/IDE/selectors/users.js
+++ b/client/modules/IDE/selectors/users.js
@@ -1,10 +1,10 @@
import { createSelector } from 'reselect';
+import getConfig from '../../../utils/getConfig';
-const __process = (typeof global !== 'undefined' ? global : window).process;
const getAuthenticated = state => state.user.authenticated;
const getTotalSize = state => state.user.totalSize;
const getAssetsTotalSize = state => state.assets.totalSize;
-const limit = __process.env.UPLOAD_LIMIT || 250000000;
+const limit = getConfig('UPLOAD_LIMIT') || 250000000;
export const getCanUploadMedia = createSelector(
getAuthenticated,
diff --git a/client/store.js b/client/store.js
index dbb3685e..a8d2114e 100644
--- a/client/store.js
+++ b/client/store.js
@@ -3,15 +3,14 @@ import thunk from 'redux-thunk';
import DevTools from './modules/App/components/DevTools';
import rootReducer from './reducers';
import { clearState, loadState } from './persistState';
-
-const __process = (typeof global !== 'undefined' ? global : window).process;
+import getConfig from './utils/getConfig';
export default function configureStore(initialState) {
const enhancers = [
applyMiddleware(thunk),
];
- if (__process.env.CLIENT && __process.env.NODE_ENV === 'development') {
+ if (getConfig('CLIENT') && getConfig('NODE_ENV') === 'development') {
// Enable DevTools only when rendering on client and during development.
enhancers.push(window.devToolsExtension ? window.devToolsExtension() : DevTools.instrument());
}
diff --git a/client/utils/getConfig.js b/client/utils/getConfig.js
new file mode 100644
index 00000000..3d8331a2
--- /dev/null
+++ b/client/utils/getConfig.js
@@ -0,0 +1,17 @@
+/**
+ * Returns config item from environment
+ */
+export default function getConfig(key) {
+ if (key == null) {
+ throw new Error('"key" must be provided to getConfig()');
+ }
+
+ const __process = (typeof global !== 'undefined' ? global : window).process;
+ const value = __process.env[key];
+
+ if (value == null) {
+ console.warn(`getConfig("${key}") returned null`);
+ }
+
+ return value;
+}
diff --git a/client/utils/getConfig.test.js b/client/utils/getConfig.test.js
new file mode 100644
index 00000000..05659cae
--- /dev/null
+++ b/client/utils/getConfig.test.js
@@ -0,0 +1,28 @@
+import getConfig from './getConfig';
+
+describe('utils/getConfig()', () => {
+ beforeEach(() => {
+ delete global.process.env.CONFIG_TEST_KEY_NAME;
+ delete window.process.env.CONFIG_TEST_KEY_NAME;
+ });
+
+ it('throws if key is not defined', () => {
+ expect(() => getConfig(/* key is missing */)).toThrow(/must be provided/);
+ });
+
+ it('fetches from global.process', () => {
+ global.process.env.CONFIG_TEST_KEY_NAME = 'editor.p5js.org';
+
+ expect(getConfig('CONFIG_TEST_KEY_NAME')).toBe('editor.p5js.org');
+ });
+
+ it('fetches from window.process', () => {
+ window.process.env.CONFIG_TEST_KEY_NAME = 'editor.p5js.org';
+
+ expect(getConfig('CONFIG_TEST_KEY_NAME')).toBe('editor.p5js.org');
+ });
+
+ it('warns but does not throw if no value found', () => {
+ expect(() => getConfig('CONFIG_TEST_KEY_NAME')).not.toThrow();
+ });
+});