From a4e7440c62daa2db244e0d56fdfaa0bbe16e1413 Mon Sep 17 00:00:00 2001 From: Christopher Joe Date: Wed, 7 Sep 2016 15:39:43 +1200 Subject: [PATCH] Added TestReactFormBuilder admin section, this utilises BasicFieldsTestPage fields currently. --- .eslintignore | 2 + .eslintrc | 6 ++ .gitignore | 2 + client/dist/bundle-legacy.js | 3 + client/src/bundles/legacy.js | 1 + client/src/legacy/TestReactFormBuilder.js | 67 ++++++++++++++++++ code/TestReactFormBuilder.php | 53 ++++++++++++++ gulpfile.js | 70 +++++++++++++++++++ package.json | 84 +++++++++++++++++++++++ 9 files changed, 288 insertions(+) create mode 100644 .eslintignore create mode 100644 .eslintrc create mode 100644 .gitignore create mode 100644 client/dist/bundle-legacy.js create mode 100644 client/src/bundles/legacy.js create mode 100644 client/src/legacy/TestReactFormBuilder.js create mode 100644 code/TestReactFormBuilder.php create mode 100644 gulpfile.js create mode 100644 package.json diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..81943c3 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +client/dist/ +client/lang/ diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..38e713e --- /dev/null +++ b/.eslintrc @@ -0,0 +1,6 @@ +{ + "extends": "airbnb", + "rules": { + "max-len": [2, 120, 4] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f43e2da --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +/**/*.js.map diff --git a/client/dist/bundle-legacy.js b/client/dist/bundle-legacy.js new file mode 100644 index 0000000..50c5e0b --- /dev/null +++ b/client/dist/bundle-legacy.js @@ -0,0 +1,3 @@ +!function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o1)for(var i=1;i does not support changing `store` on the fly. It is most likely that you see this error because you updated to Redux 2.x and React Redux 2.x which no longer hot reload reducers automatically. See https://github.com/reactjs/react-redux/releases/tag/v2.0.0 for the migration instructions."))}exports.__esModule=!0,exports["default"]=void 0;var _react=require("react"),_storeShape=require("../utils/storeShape"),_storeShape2=_interopRequireDefault(_storeShape),_warning=require("../utils/warning"),_warning2=_interopRequireDefault(_warning),didWarnAboutReceivingStore=!1,Provider=function(_Component){function Provider(props,context){_classCallCheck(this,Provider);var _this=_possibleConstructorReturn(this,_Component.call(this,props,context));return _this.store=props.store,_this}return _inherits(Provider,_Component),Provider.prototype.getChildContext=function(){return{store:this.store}},Provider.prototype.render=function(){var children=this.props.children;return _react.Children.only(children)},Provider}(_react.Component);exports["default"]=Provider,"production"!==process.env.NODE_ENV&&(Provider.prototype.componentWillReceiveProps=function(nextProps){var store=this.store,nextStore=nextProps.store;store!==nextStore&&warnAboutReceivingStore()}),Provider.propTypes={store:_storeShape2["default"].isRequired,children:_react.PropTypes.element.isRequired},Provider.childContextTypes={store:_storeShape2["default"].isRequired}}).call(this,require("_process"))},{"../utils/storeShape":8,"../utils/warning":9,_process:3,react:"react"}],5:[function(require,module,exports){(function(process){"use strict";function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(self,call){if(!self)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!call||"object"!=typeof call&&"function"!=typeof call?self:call}function _inherits(subClass,superClass){if("function"!=typeof superClass&&null!==superClass)throw new TypeError("Super expression must either be null or a function, not "+typeof superClass);subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,enumerable:!1,writable:!0,configurable:!0}}),superClass&&(Object.setPrototypeOf?Object.setPrototypeOf(subClass,superClass):subClass.__proto__=superClass)}function getDisplayName(WrappedComponent){return WrappedComponent.displayName||WrappedComponent.name||"Component"}function tryCatch(fn,ctx){try{return fn.apply(ctx)}catch(e){return errorObject.value=e,errorObject}}function connect(mapStateToProps,mapDispatchToProps,mergeProps){var options=arguments.length<=3||void 0===arguments[3]?{}:arguments[3],shouldSubscribe=Boolean(mapStateToProps),mapState=mapStateToProps||defaultMapStateToProps,mapDispatch=void 0;mapDispatch="function"==typeof mapDispatchToProps?mapDispatchToProps:mapDispatchToProps?(0,_wrapActionCreators2["default"])(mapDispatchToProps):defaultMapDispatchToProps;var finalMergeProps=mergeProps||defaultMergeProps,_options$pure=options.pure,pure=void 0===_options$pure||_options$pure,_options$withRef=options.withRef,withRef=void 0!==_options$withRef&&_options$withRef,checkMergedEquals=pure&&finalMergeProps!==defaultMergeProps,version=nextVersion++;return function(WrappedComponent){function checkStateShape(props,methodName){(0,_isPlainObject2["default"])(props)||(0,_warning2["default"])(methodName+"() in "+connectDisplayName+" must return a plain object. "+("Instead received "+props+"."))}function computeMergedProps(stateProps,dispatchProps,parentProps){var mergedProps=finalMergeProps(stateProps,dispatchProps,parentProps);return"production"!==process.env.NODE_ENV&&checkStateShape(mergedProps,"mergeProps"),mergedProps}var connectDisplayName="Connect("+getDisplayName(WrappedComponent)+")",Connect=function(_Component){function Connect(props,context){_classCallCheck(this,Connect);var _this=_possibleConstructorReturn(this,_Component.call(this,props,context));_this.version=version,_this.store=props.store||context.store,(0,_invariant2["default"])(_this.store,'Could not find "store" in either the context or '+('props of "'+connectDisplayName+'". ')+"Either wrap the root component in a , "+('or explicitly pass "store" as a prop to "'+connectDisplayName+'".'));var storeState=_this.store.getState();return _this.state={storeState:storeState},_this.clearCache(),_this}return _inherits(Connect,_Component),Connect.prototype.shouldComponentUpdate=function(){return!pure||this.haveOwnPropsChanged||this.hasStoreStateChanged},Connect.prototype.computeStateProps=function(store,props){if(!this.finalMapStateToProps)return this.configureFinalMapState(store,props);var state=store.getState(),stateProps=this.doStatePropsDependOnOwnProps?this.finalMapStateToProps(state,props):this.finalMapStateToProps(state);return"production"!==process.env.NODE_ENV&&checkStateShape(stateProps,"mapStateToProps"),stateProps},Connect.prototype.configureFinalMapState=function(store,props){var mappedState=mapState(store.getState(),props),isFactory="function"==typeof mappedState;return this.finalMapStateToProps=isFactory?mappedState:mapState,this.doStatePropsDependOnOwnProps=1!==this.finalMapStateToProps.length,isFactory?this.computeStateProps(store,props):("production"!==process.env.NODE_ENV&&checkStateShape(mappedState,"mapStateToProps"),mappedState)},Connect.prototype.computeDispatchProps=function(store,props){if(!this.finalMapDispatchToProps)return this.configureFinalMapDispatch(store,props);var dispatch=store.dispatch,dispatchProps=this.doDispatchPropsDependOnOwnProps?this.finalMapDispatchToProps(dispatch,props):this.finalMapDispatchToProps(dispatch);return"production"!==process.env.NODE_ENV&&checkStateShape(dispatchProps,"mapDispatchToProps"),dispatchProps},Connect.prototype.configureFinalMapDispatch=function(store,props){var mappedDispatch=mapDispatch(store.dispatch,props),isFactory="function"==typeof mappedDispatch;return this.finalMapDispatchToProps=isFactory?mappedDispatch:mapDispatch,this.doDispatchPropsDependOnOwnProps=1!==this.finalMapDispatchToProps.length,isFactory?this.computeDispatchProps(store,props):("production"!==process.env.NODE_ENV&&checkStateShape(mappedDispatch,"mapDispatchToProps"),mappedDispatch)},Connect.prototype.updateStatePropsIfNeeded=function(){var nextStateProps=this.computeStateProps(this.store,this.props);return(!this.stateProps||!(0,_shallowEqual2["default"])(nextStateProps,this.stateProps))&&(this.stateProps=nextStateProps,!0)},Connect.prototype.updateDispatchPropsIfNeeded=function(){var nextDispatchProps=this.computeDispatchProps(this.store,this.props);return(!this.dispatchProps||!(0,_shallowEqual2["default"])(nextDispatchProps,this.dispatchProps))&&(this.dispatchProps=nextDispatchProps,!0)},Connect.prototype.updateMergedPropsIfNeeded=function(){var nextMergedProps=computeMergedProps(this.stateProps,this.dispatchProps,this.props);return!(this.mergedProps&&checkMergedEquals&&(0,_shallowEqual2["default"])(nextMergedProps,this.mergedProps))&&(this.mergedProps=nextMergedProps,!0)},Connect.prototype.isSubscribed=function(){return"function"==typeof this.unsubscribe},Connect.prototype.trySubscribe=function(){shouldSubscribe&&!this.unsubscribe&&(this.unsubscribe=this.store.subscribe(this.handleChange.bind(this)),this.handleChange())},Connect.prototype.tryUnsubscribe=function(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null)},Connect.prototype.componentDidMount=function(){this.trySubscribe()},Connect.prototype.componentWillReceiveProps=function(nextProps){pure&&(0,_shallowEqual2["default"])(nextProps,this.props)||(this.haveOwnPropsChanged=!0)},Connect.prototype.componentWillUnmount=function(){this.tryUnsubscribe(),this.clearCache()},Connect.prototype.clearCache=function(){this.dispatchProps=null,this.stateProps=null,this.mergedProps=null,this.haveOwnPropsChanged=!0,this.hasStoreStateChanged=!0,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,this.renderedElement=null,this.finalMapDispatchToProps=null,this.finalMapStateToProps=null},Connect.prototype.handleChange=function(){if(this.unsubscribe){var storeState=this.store.getState(),prevStoreState=this.state.storeState;if(!pure||prevStoreState!==storeState){if(pure&&!this.doStatePropsDependOnOwnProps){var haveStatePropsChanged=tryCatch(this.updateStatePropsIfNeeded,this);if(!haveStatePropsChanged)return;haveStatePropsChanged===errorObject&&(this.statePropsPrecalculationError=errorObject.value),this.haveStatePropsBeenPrecalculated=!0}this.hasStoreStateChanged=!0,this.setState({storeState:storeState})}}},Connect.prototype.getWrappedInstance=function(){return(0,_invariant2["default"])(withRef,"To access the wrapped instance, you need to specify { withRef: true } as the fourth argument of the connect() call."),this.refs.wrappedInstance},Connect.prototype.render=function(){var haveOwnPropsChanged=this.haveOwnPropsChanged,hasStoreStateChanged=this.hasStoreStateChanged,haveStatePropsBeenPrecalculated=this.haveStatePropsBeenPrecalculated,statePropsPrecalculationError=this.statePropsPrecalculationError,renderedElement=this.renderedElement;if(this.haveOwnPropsChanged=!1,this.hasStoreStateChanged=!1,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,statePropsPrecalculationError)throw statePropsPrecalculationError;var shouldUpdateStateProps=!0,shouldUpdateDispatchProps=!0;pure&&renderedElement&&(shouldUpdateStateProps=hasStoreStateChanged||haveOwnPropsChanged&&this.doStatePropsDependOnOwnProps,shouldUpdateDispatchProps=haveOwnPropsChanged&&this.doDispatchPropsDependOnOwnProps);var haveStatePropsChanged=!1,haveDispatchPropsChanged=!1;haveStatePropsBeenPrecalculated?haveStatePropsChanged=!0:shouldUpdateStateProps&&(haveStatePropsChanged=this.updateStatePropsIfNeeded()),shouldUpdateDispatchProps&&(haveDispatchPropsChanged=this.updateDispatchPropsIfNeeded());var haveMergedPropsChanged=!0;return haveMergedPropsChanged=!!(haveStatePropsChanged||haveDispatchPropsChanged||haveOwnPropsChanged)&&this.updateMergedPropsIfNeeded(),!haveMergedPropsChanged&&renderedElement?renderedElement:(withRef?this.renderedElement=(0,_react.createElement)(WrappedComponent,_extends({},this.mergedProps,{ref:"wrappedInstance"})):this.renderedElement=(0,_react.createElement)(WrappedComponent,this.mergedProps),this.renderedElement)},Connect}(_react.Component);return Connect.displayName=connectDisplayName,Connect.WrappedComponent=WrappedComponent,Connect.contextTypes={store:_storeShape2["default"]},Connect.propTypes={store:_storeShape2["default"]},"production"!==process.env.NODE_ENV&&(Connect.prototype.componentWillUpdate=function(){this.version!==version&&(this.version=version,this.trySubscribe(),this.clearCache())}),(0,_hoistNonReactStatics2["default"])(Connect,WrappedComponent)}}var _extends=Object.assign||function(target){for(var i=1;i0?"Unexpected "+(unexpectedKeys.length>1?"keys":"key")+" "+('"'+unexpectedKeys.join('", "')+'" found in '+argumentName+". ")+"Expected to find one of the known reducer keys instead: "+('"'+reducerKeys.join('", "')+'". Unexpected keys will be ignored.'):void 0}function assertReducerSanity(reducers){Object.keys(reducers).forEach(function(key){var reducer=reducers[key],initialState=reducer(void 0,{type:_createStore.ActionTypes.INIT});if("undefined"==typeof initialState)throw new Error('Reducer "'+key+'" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined.');var type="@@redux/PROBE_UNKNOWN_ACTION_"+Math.random().toString(36).substring(7).split("").join(".");if("undefined"==typeof reducer(void 0,{type:type}))throw new Error('Reducer "'+key+'" returned undefined when probed with a random type. '+("Don't try to handle "+_createStore.ActionTypes.INIT+' or other actions in "redux/*" ')+"namespace. They are considered private. Instead, you must return the current state for any unknown actions, unless it is undefined, in which case you must return the initial state, regardless of the action type. The initial state may not be undefined.")})}function combineReducers(reducers){var sanityError,finalReducers=_pick2["default"](reducers,function(val){return"function"==typeof val});try{assertReducerSanity(finalReducers)}catch(e){sanityError=e}var defaultState=_mapValues2["default"](finalReducers,function(){});return function(state,action){if(void 0===state&&(state=defaultState),sanityError)throw sanityError;var hasChanged=!1,finalState=_mapValues2["default"](finalReducers,function(reducer,key){var previousStateForKey=state[key],nextStateForKey=reducer(previousStateForKey,action);if("undefined"==typeof nextStateForKey){var errorMessage=getUndefinedStateErrorMessage(key,action);throw new Error(errorMessage)}return hasChanged=hasChanged||nextStateForKey!==previousStateForKey,nextStateForKey});if("production"!==process.env.NODE_ENV){var warningMessage=getUnexpectedStateKeyWarningMessage(state,finalState,action);warningMessage&&console.error(warningMessage)}return hasChanged?finalState:state}}exports.__esModule=!0,exports["default"]=combineReducers;var _createStore=require("../createStore"),_isPlainObject=require("./isPlainObject"),_isPlainObject2=_interopRequireDefault(_isPlainObject),_mapValues=require("./mapValues"),_mapValues2=_interopRequireDefault(_mapValues),_pick=require("./pick"),_pick2=_interopRequireDefault(_pick);module.exports=exports["default"]}).call(this,require("_process")); +},{"../createStore":18,"./isPlainObject":24,"./mapValues":25,"./pick":26,_process:3}],23:[function(require,module,exports){"use strict";function compose(){for(var _len=arguments.length,funcs=Array(_len),_key=0;_key<_len;_key++)funcs[_key]=arguments[_key];return function(arg){return funcs.reduceRight(function(composed,f){return f(composed)},arg)}}exports.__esModule=!0,exports["default"]=compose,module.exports=exports["default"]},{}],24:[function(require,module,exports){"use strict";function isPlainObject(obj){if(!obj||"object"!=typeof obj)return!1;var proto="function"==typeof obj.constructor?Object.getPrototypeOf(obj):Object.prototype;if(null===proto)return!0;var constructor=proto.constructor;return"function"==typeof constructor&&constructor instanceof constructor&&fnToString(constructor)===objStringValue}exports.__esModule=!0,exports["default"]=isPlainObject;var fnToString=function(fn){return Function.prototype.toString.call(fn)},objStringValue=fnToString(Object);module.exports=exports["default"]},{}],25:[function(require,module,exports){"use strict";function mapValues(obj,fn){return Object.keys(obj).reduce(function(result,key){return result[key]=fn(obj[key],key),result},{})}exports.__esModule=!0,exports["default"]=mapValues,module.exports=exports["default"]},{}],26:[function(require,module,exports){"use strict";function pick(obj,fn){return Object.keys(obj).reduce(function(result,key){return fn(obj[key])&&(result[key]=obj[key]),result},{})}exports.__esModule=!0,exports["default"]=pick,module.exports=exports["default"]},{}]},{},[1]); +//# sourceMappingURL=bundle-legacy.js.map diff --git a/client/src/bundles/legacy.js b/client/src/bundles/legacy.js new file mode 100644 index 0000000..4aaa4ec --- /dev/null +++ b/client/src/bundles/legacy.js @@ -0,0 +1 @@ +require('../legacy/TestReactFormBuilder'); diff --git a/client/src/legacy/TestReactFormBuilder.js b/client/src/legacy/TestReactFormBuilder.js new file mode 100644 index 0000000..bfca34c --- /dev/null +++ b/client/src/legacy/TestReactFormBuilder.js @@ -0,0 +1,67 @@ +import jQuery from 'jQuery'; +import i18n from 'i18n'; +import React from 'react'; +import ReactDOM from 'react-dom'; +import { Provider } from 'react-redux'; +import FormBuilder from 'components/FormBuilder/FormBuilder'; + +jQuery.entwine('ss', ($) => { + /** + * Kick off Test React FormBuilder admin section. + * Uses React to rebuild the list of fields from FrameworkTest's TestPages. + */ + $('.cms-content.TestReactFormBuilder').entwine({ + onmatch() { + setTimeout(() => this._renderForm(), 100); + }, + + onunmatch() { + this._clearForm(); + }, + + open() { + this._renderForm(); + }, + + close() { + this._clearForm(); + }, + + _renderForm() { + const store = window.ss.store; + const sectionConfig = store.getState() + .config.sections['TestReactFormBuilder']; + const schemaUrl = sectionConfig.form.TestEditForm.schemaUrl; + + ReactDOM.render( + + this._handleSubmit(...args)} + /> + , + this[0] + ); + }, + + _clearForm() { + ReactDOM.unmountComponentAtNode(this[0]); + // this.empty(); + }, + + _handleSubmit(event, fieldValues, submitFn) { + event.preventDefault(); + + return submitFn(); + }, + + }); + + $('.cms-content.TestReactFormBuilder .nav-link').entwine({ + onclick: function (e) { + // this is required because the React version of e.preventDefault() doesn't work + // this is to stop React Tabs from navigating the page + e.preventDefault(); + } + }); +}); diff --git a/code/TestReactFormBuilder.php b/code/TestReactFormBuilder.php new file mode 100644 index 0000000..5cc9e93 --- /dev/null +++ b/code/TestReactFormBuilder.php @@ -0,0 +1,53 @@ +Link(); + return array_merge(parent::getClientConfig(), [ + 'reactRouter' => false, + 'form' => [ + 'TestEditForm' => [ + 'schemaUrl' => $this->Link('schema/TestEditForm'), + ], + ] + ]); + } + public function getTestEditForm($id = null) { + /* @var $page BasicFieldsTestPage */ + $page = BasicFieldsTestPage::create(); + + $form = Form::create($this, 'TestEditForm', $page->getCMSFields(), FieldList::create([])); + return $form; + } + + public function TestEditForm() { + return $this->getTestEditForm(); + } + + /** + * @todo Implement on client + * + * @param bool $unlinked + * @return ArrayList + */ + public function breadcrumbs($unlinked = false) + { + return null; + } + + public function getEditForm($id = null, $fields = null) { + Requirements::javascript('frameworktest/client/dist/bundle-legacy.js'); + + return Form::create($this, 'TestEditForm', FieldList::create(), FieldList::create()); + } +} diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..771a8be --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,70 @@ +const gulp = require('gulp'); +const browserify = require('browserify'); +const buffer = require('vinyl-buffer'); +const sourcemaps = require('gulp-sourcemaps'); +const uglify = require('gulp-uglify'); +const gulpUtil = require('gulp-util'); +const notify = require('gulp-notify'); +const source = require('vinyl-source-stream'); + +const isDev = typeof process.env.npm_config_development !== 'undefined'; + +const PATHS = { + JS_SRC: './client/src', + JS_DIST: './client/dist', +}; + +const browserifyOptions = { + debug: true, + paths: [PATHS.JS_SRC], +}; + +const babelifyOptions = { + presets: ['es2015', 'es2015-ie', 'react'], + plugins: ['transform-object-assign', 'transform-object-rest-spread'], + ignore: /(node_modules|thirdparty)/, + comments: false, +}; + +const uglifyOptions = { + mangle: false, +}; + +gulp.task('build', ['bundle']); + +gulp.task('bundle', ['bundle-legacy']); + +gulp.task('bundle-legacy', function bundleLeftAndMain() { + const bundleFileName = 'bundle-legacy.js'; + + return browserify(Object.assign({}, browserifyOptions, + { entries: `${PATHS.JS_SRC}/bundles/legacy.js` } + )) + .on('update', bundleLeftAndMain) + .on('log', (msg) => + gulpUtil.log('Finished', `bundled ${bundleFileName} ${msg}`) + ) + .transform('babelify', babelifyOptions) + .external('config') + .external('jQuery') + .external('i18n') + .external('i18nx') + .external('react') + .external('react-dom') + .external('components/FormBuilder/FormBuilder') + .bundle() + .on('update', bundleLeftAndMain) + .on('error', notify.onError({ message: `${bundleFileName}: <%= error.message %>` })) + .pipe(source(bundleFileName)) + .pipe(buffer()) + .pipe(sourcemaps.init({ loadMaps: true })) + .pipe(uglify(uglifyOptions)) + .pipe(sourcemaps.write('./')) + .pipe(gulp.dest(PATHS.JS_DIST)); +}); + +gulp.task('default', ['build'], () => { + if (isDev) { + gulp.watch(`${PATHS.JS_SRC}/**/*.js`, ['build']); + } +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..459d7f8 --- /dev/null +++ b/package.json @@ -0,0 +1,84 @@ +{ + "name": "silverstripe-asset-admin", + "version": "0.0.0", + "description": "Asset management for the SilverStripe CMS", + "main": "./client/src/boot/index.js", + "license": "BSD-3-Clause", + "repository": { + "type": "git", + "url": "git+https://github.com/open-sausages/silverstripe-asset-admin.git" + }, + "homepage": "https://github.com/open-sausages/silverstripe-asset-admin", + "bugs": { + "url": "https://github.com/open-sausages/silverstripe-asset-admin/issues" + }, + "author": "SilverStripe Ltd", + "engines": { + "node": "4.x" + }, + "scripts": { + "build": "gulp", + "test": "NODE_PATH=\"./client/src:../framework/client/src:../framework/admin/client/src\" jest", + "coverage": "jest --coverage", + "lock": "npm-shrinkwrap --dev", + "lint": "eslint client/src" + }, + "jest": { + "scriptPreprocessor": "/node_modules/babel-jest", + "testDirectoryName": "tests", + "unmockedModulePathPatterns": [ + "/node_modules/react" + ], + "mocksPattern": "mocks", + "testPathDirs": [ + "client/src" + ], + "bail": true, + "testRunner": "/node_modules/jest-cli/src/testRunners/jasmine/jasmine2.js" + }, + "devDependencies": { + "babel-core": "^6.7.7", + "babel-jest": "^11.0.2", + "babel-plugin-transform-es2015-modules-umd": "^6.6.5", + "babel-plugin-transform-object-assign": "^6.5.0", + "babel-plugin-transform-object-rest-spread": "^6.8.0", + "babel-preset-es2015": "^6.6.0", + "babel-preset-es2015-ie": "^6.6.1", + "babel-preset-react": "^6.5.0", + "babelify": "^7.2.0", + "browserify": "^11.1.0", + "deep-freeze-strict": "^1.1.1", + "eslint": "^2.5.3", + "eslint-config-airbnb": "^6.2.0", + "eslint-plugin-react": "^4.2.3", + "gulp": "^3.9.0", + "gulp-if": "^2.0.0", + "gulp-notify": "^2.2.0", + "gulp-sourcemaps": "^1.6.0", + "gulp-uglify": "^1.5.2", + "jest-cli": "^0.9.2", + "npm-shrinkwrap": "^200.4.0", + "react": "^0.14.8", + "react-addons-css-transition-group": "^0.14.8", + "react-bootstrap-ss": "^0.30.5", + "react-dom": "^0.14.8", + "react-redux": "^4.4.1", + "react-router": "^2.4.1", + "react-router-redux": "^4.0.5", + "redux": "https://registry.npmjs.org/redux/-/redux-3.0.5.tgz", + "redux-thunk": "^2.1.0", + "semver": "^5.0.3", + "vinyl-buffer": "^1.0.0", + "vinyl-source-stream": "^1.1.0", + "watchify": "^3.7.0" + }, + "dependencies": { + "gulp-util": "^3.0.7" + }, + "babel": { + "presets": [ + "react", + "es2015" + ] + } +}