canner
Version:
Build CMS in few lines of code for different data sources
635 lines (522 loc) • 20.8 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var React = _interopRequireWildcard(require("react"));
var _context = require("../hocs/context");
var _reactApollo = require("react-apollo");
var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
var _pluralize = _interopRequireDefault(require("pluralize"));
var _upperFirst = _interopRequireDefault(require("lodash/upperFirst"));
var _action = require("../action");
var _query = require("../query");
var _onDeployManager = require("../onDeployManager");
var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
var _utils = require("../query/utils");
var _mapValues = _interopRequireDefault(require("lodash/mapValues"));
var _lodash = require("lodash");
var _log = _interopRequireDefault(require("../utils/log"));
function _templateObject5() {
var data = (0, _taggedTemplateLiteral2.default)(["", ""]);
_templateObject5 = function _templateObject5() {
return data;
};
return data;
}
function _templateObject4() {
var data = (0, _taggedTemplateLiteral2.default)(["", ""]);
_templateObject4 = function _templateObject4() {
return data;
};
return data;
}
function _templateObject3() {
var data = (0, _taggedTemplateLiteral2.default)(["", ""]);
_templateObject3 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2() {
var data = (0, _taggedTemplateLiteral2.default)(["", ""]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject() {
var data = (0, _taggedTemplateLiteral2.default)(["", ""]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
var Provider =
/*#__PURE__*/
function (_React$PureComponent) {
(0, _inherits2.default)(Provider, _React$PureComponent);
function Provider(props) {
var _this;
(0, _classCallCheck2.default)(this, Provider);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Provider).call(this, props));
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "actionManager", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "query", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "observableQueryMap", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "onDeployManager", void 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "state", {
dataChanged: {}
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "genQuery", function () {
var schema = _this.props.schema;
_this.query = new _query.Query({
schema: schema
});
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "genObservableQueryMap", function () {
var _this$props = _this.props,
schema = _this$props.schema,
routes = _this$props.routes,
routerParams = _this$props.routerParams;
_this.observableQueryMap = (0, _mapValues.default)(schema, function (v, key) {
if (routes[0] === key) {
return _this.getObservable({
routes: routes,
operator: routerParams.operator
});
}
return _this.getObservable({
routes: [key],
operator: 'update'
});
});
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "getObservable", function (_ref) {
var routes = _ref.routes,
operator = _ref.operator;
var _this$props2 = _this.props,
client = _this$props2.client,
schema = _this$props2.schema,
beforeFetch = _this$props2.beforeFetch;
var key = routes[0];
var variables = _this.query && _this.query.getVairables();
var customizedGQL = routes.length === 1 && operator === 'update' && schema[key].graphql;
var fetchPolicy = schema[key].fetchPolicy;
var query = '';
if (customizedGQL) {
query = schema[key].graphql;
} else {
query = _this.query.toGQL(key);
}
if (beforeFetch) {
var updated = beforeFetch(key, {
query: query,
variables: variables,
relation: schema[key].relation
});
query = updated.query;
variables = updated.variables;
}
return client.watchQuery({
query: (0, _graphqlTag.default)(_templateObject(), query),
variables: variables,
fetchPolicy: routes.length > 1 && operator === 'update' ? fetchPolicy : 'cache-first'
});
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "updateDataChanged", function () {
var dataDidChange = _this.props.dataDidChange;
var actions = _this.actionManager.getActions();
var dataChanged = (0, _lodash.groupBy)(actions, function (action) {
return action.payload.key;
});
dataChanged = (0, _mapValues.default)(dataChanged, function (value) {
if (value[0].type === 'UPDATE_OBJECT') {
return true;
}
return value.map(function (v) {
return v.payload.id;
});
});
if (dataDidChange) {
dataDidChange(dataChanged);
}
_this.setState({
dataChanged: dataChanged
});
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "updateQuery", function (paths, args) {
var _this$props3 = _this.props,
routerParams = _this$props3.routerParams,
schema = _this$props3.schema,
routes = _this$props3.routes,
beforeFetch = _this$props3.beforeFetch,
rootKey = _this$props3.rootKey;
var originVariables = _this.query.getVairables();
_this.query.updateQueries(paths, 'args', args);
var variables = _this.query.getVairables();
var reWatchQuery = compareVariables(originVariables, variables);
if (reWatchQuery) {
_this.observableQueryMap[paths[0]] = _this.getObservable({
routes: paths,
operator: routerParams.operator
});
(0, _log.default)('updateQuery rewatch', variables, args);
return Promise.resolve(reWatchQuery);
} else {
var refetch = routes.length > 1 && schema[paths[0]] && schema[paths[0]].refetch;
if (beforeFetch) {
var updated = beforeFetch(rootKey, {
query: '',
variables: variables,
relation: schema[rootKey].relation
});
variables = updated.variables;
}
(0, _log.default)('updateQuery', variables, args);
if (refetch) {
return _this.observableQueryMap[paths[0]].refetch(variables).then(function () {
return false;
});
}
return _this.observableQueryMap[paths[0]].setVariables(variables).then(function () {
return false;
});
}
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "fetch", function (key) {
var errorHandler = _this.props.errorHandler;
var observabale = _this.observableQueryMap[key];
var currentResult = observabale.currentResult();
var loading = currentResult.loading,
error = currentResult.error;
if (loading) {
return observabale.result().then(function (result) {
(0, _log.default)('fetch', 'loading', key, result);
return result.data;
}).catch(function (e) {
(0, _log.default)('fetch', 'network error', key, e);
errorHandler && errorHandler(e);
});
} else if (error) {
var lastResult = observabale.getLastResult();
(0, _log.default)('fetch', 'error', key, lastResult);
errorHandler && errorHandler(error);
return Promise.resolve(lastResult.data);
} else {
(0, _log.default)('fetch', 'loaded', key, currentResult, _this.query.getVairables());
return Promise.resolve(currentResult.data);
}
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "subscribe", function (key, callback) {
var observableQuery = _this.observableQueryMap[key];
return observableQuery.subscribe({
next: function next() {
var _observableQuery$curr = observableQuery.currentResult(),
loading = _observableQuery$curr.loading,
errors = _observableQuery$curr.errors,
data = _observableQuery$curr.data;
if (!loading && !errors && data && !(0, _isEmpty.default)(data)) {
callback(data);
}
},
error: function error() {// ignore the error here since in fetch method, the error should be handled
}
});
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "executeOnDeploy", function (key, value) {
return _this.onDeployManager.execute({
key: key,
value: value
});
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "deploy", function (key, id) {
var _this$props4 = _this.props,
client = _this$props4.client,
afterDeploy = _this$props4.afterDeploy,
schema = _this$props4.schema,
errorHandler = _this$props4.errorHandler,
routes = _this$props4.routes,
rootKey = _this$props4.rootKey,
routerParams = _this$props4.routerParams,
beforeDeploy = _this$props4.beforeDeploy,
beforeFetch = _this$props4.beforeFetch;
var actions = _this.actionManager.getActions(key, id);
if (!actions || !actions.length) {
return Promise.resolve();
}
actions = removeIdInCreateArray(actions);
var mutation = (0, _utils.objectToQueries)((0, _action.actionToMutation)(actions[0]), false);
var variables = (0, _action.actionsToVariables)(actions, schema);
var queryVariables = _this.query.getVairables();
var query = null;
if (routes.length === 1 && routerParams.operator === 'update' && schema[rootKey].graphql) {
query = schema[rootKey].graphql;
} else {
query = _this.query.toGQL(actions[0].payload.key);
}
if (beforeFetch) {
var updated = beforeFetch(rootKey, {
query: query,
variables: queryVariables,
relation: schema[rootKey].relation
});
variables = updated.variables;
query = updated.query;
}
var cachedData = client.readQuery({
query: (0, _graphqlTag.default)(_templateObject2(), query),
variables: queryVariables
});
var mutatedData = cachedData[key];
var _this$executeOnDeploy = _this.executeOnDeploy(key, mutatedData),
error = _this$executeOnDeploy.error;
if (error) {
errorHandler && errorHandler(new Error('Invalid field'));
return Promise.reject(error);
}
if (beforeDeploy) {
var _updated = beforeDeploy(key, {
mutation: mutation,
variables: variables
});
mutation = _updated.mutation;
variables = _updated.variables;
}
return client.mutate({
mutation: (0, _graphqlTag.default)(_templateObject3(), mutation),
variables: variables
}).then(function (result) {
if (actions[0].type === 'CREATE_ARRAY') {
_this.updateID({
action: actions[0],
result: result
});
client.resetStore();
}
(0, _log.default)('deploy', key, {
id: id,
result: result,
mutation: mutation,
variables: variables
});
_this.actionManager.removeActions(key, id);
return result.data;
}).then(function (result) {
_this.updateDataChanged();
afterDeploy && afterDeploy({
key: key,
id: id || '',
result: result,
actions: actions
});
return result;
}).catch(function (e) {
errorHandler && errorHandler(e);
(0, _log.default)('deploy', e, key, {
id: id,
mutation: mutation,
variables: variables
}); // to hocs
throw e;
});
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "reset", function (key, id) {
var rootKey = _this.props.rootKey;
if (_this.actionManager.getActions(key, id).length === 0) {
return Promise.resolve();
}
_this.actionManager.removeActions(key, id);
_this.updateDataChanged();
var variables = _this.query.getVairables();
if (_this.observableQueryMap[key || rootKey]) {
return _this.observableQueryMap[key || rootKey].refetch(variables);
}
return Promise.resolve();
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "request", function (action) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
write: true
};
var _options$write = options.write,
write = _options$write === void 0 ? true : _options$write;
var actions = [].concat(action);
if (actions.length === 0) {
return Promise.resolve();
}
actions.forEach(function (ac) {
return _this.actionManager.addAction(ac);
});
_this.updateDataChanged();
if (write) {
var _this$updateCachedDat = _this.updateCachedData(actions),
_data = _this$updateCachedDat.data,
mutatedData = _this$updateCachedDat.mutatedData;
(0, _log.default)('request', action, _data, mutatedData);
}
return Promise.resolve();
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "updateCachedData", function (actions) {
var _this$props5 = _this.props,
client = _this$props5.client,
schema = _this$props5.schema,
routes = _this$props5.routes,
rootKey = _this$props5.rootKey,
routerParams = _this$props5.routerParams,
beforeFetch = _this$props5.beforeFetch;
var variables = _this.query.getVairables();
var query = null;
if (routes.length === 1 && routerParams.operator === 'update' && schema[rootKey].graphql) {
query = schema[rootKey].graphql;
} else {
query = _this.query.toGQL(actions[0].payload.key);
}
if (beforeFetch) {
var updated = beforeFetch(rootKey, {
query: query,
variables: variables,
relation: schema[rootKey].relation
});
variables = updated.variables;
query = updated.query;
}
var data = client.readQuery({
query: (0, _graphqlTag.default)(_templateObject4(), query),
variables: variables
});
var mutatedData = actions.reduce(function (result, ac) {
return (0, _action.mutate)(result, ac);
}, data);
client.writeQuery({
query: query,
variables: variables,
data: mutatedData
});
return {
data: data,
mutatedData: mutatedData
};
});
_this.actionManager = new _action.ActionManager();
_this.genQuery();
_this.genObservableQueryMap();
_this.onDeployManager = new _onDeployManager.OnDeployManager();
return _this;
}
(0, _createClass2.default)(Provider, [{
key: "UNSAFE_componentWillReceiveProps",
value: function UNSAFE_componentWillReceiveProps(nextProps) {
var rootKey = nextProps.rootKey,
routes = nextProps.routes,
schema = nextProps.schema,
routerParams = nextProps.routerParams;
var customizedGQL = schema[rootKey] && schema[rootKey].graphql;
if (customizedGQL) {
this.observableQueryMap[rootKey] = this.getObservable({
routes: routes,
operator: routerParams.operator
});
}
}
}, {
key: "updateID",
value: function updateID(_ref2) {
var action = _ref2.action,
result = _ref2.result;
var client = this.props.client;
var originId = action.payload.id;
var key = action.payload.key;
var resultKey = "create".concat((0, _upperFirst.default)(_pluralize.default.singular(key)));
var newId = result.data[resultKey].id;
var variables = this.query.getVairables();
var query = (0, _graphqlTag.default)(_templateObject5(), this.query.toGQL(key));
var data = client.readQuery({
query: query,
variables: variables
});
data[key].edges.map(function (edge) {
if (edge.cursor === originId) {
edge.cursor = newId;
edge.node.id = newId;
}
return edge;
});
client.writeQuery({
query: query,
variables: variables,
data: data
});
}
}, {
key: "render",
value: function render() {
var _this$props6 = this.props,
client = _this$props6.client,
beforeFetch = _this$props6.beforeFetch;
return React.createElement(_reactApollo.ApolloProvider, {
client: client
}, React.createElement(_context.HOCContext.Provider, {
value: {
request: this.request,
deploy: this.deploy,
fetch: this.fetch,
reset: this.reset,
updateQuery: this.updateQuery,
subscribe: this.subscribe,
query: this.query,
onDeploy: this.onDeployManager.registerCallback,
removeOnDeploy: this.onDeployManager.unregisterCallback,
dataChanged: this.state.dataChanged,
beforeFetch: beforeFetch
}
}, React.cloneElement(this.props.children, {
request: this.request,
deploy: this.deploy,
fetch: this.fetch,
reset: this.reset,
updateQuery: this.updateQuery,
subscribe: this.subscribe,
query: this.query,
onDeploy: this.onDeployManager.registerCallback,
removeOnDeploy: this.onDeployManager.unregisterCallback,
beforeFetch: beforeFetch
})));
}
}]);
return Provider;
}(React.PureComponent);
exports.default = Provider;
function removeIdInCreateArray(actions) {
return actions.map(function (action) {
if (action.type === 'CREATE_ARRAY') {
var newAction = JSON.parse(JSON.stringify(action));
delete newAction.payload.value.id;
delete newAction.payload.value.__typename;
return newAction;
}
return action;
});
}
function compareVariables(originVariables, variables) {
var originArr = Object.keys(originVariables).filter(function (key) {
return originVariables[key];
});
var varArr = Object.keys(variables).filter(function (key) {
return variables[key];
});
var less = (0, _lodash.difference)(originArr, varArr);
var more = (0, _lodash.difference)(varArr, originArr);
if (less.length === 0 && more.length === 0) {
return false;
}
return true;
}