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(); + }); +});