@thoughtbot/superglue 0.0.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -0
- package/action_creators/index.js +160 -0
- package/action_creators/requests.js +207 -0
- package/actions.js +28 -0
- package/components/Nav.js +186 -0
- package/components/RailsTag.js +71 -0
- package/config.js +9 -0
- package/index.js +263 -0
- package/middleware.js +80 -0
- package/package.json +48 -6
- package/reducers/index.js +288 -0
- package/utils/helpers.js +36 -0
- package/utils/immutability.js +176 -0
- package/utils/index.js +59 -0
- package/utils/react.js +52 -0
- package/utils/request.js +132 -0
- package/utils/ujs.js +138 -0
- package/utils/url.js +126 -0
- package/utils/window.js +15 -0
package/utils/request.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.argsForFetch = argsForFetch;
|
|
5
|
+
exports.extractJSON = extractJSON;
|
|
6
|
+
exports.handleServerErrors = handleServerErrors;
|
|
7
|
+
exports.isValidContent = isValidContent;
|
|
8
|
+
exports.isValidResponse = isValidResponse;
|
|
9
|
+
exports.parseResponse = parseResponse;
|
|
10
|
+
exports.validateResponse = validateResponse;
|
|
11
|
+
|
|
12
|
+
var _urlParse = _interopRequireDefault(require("url-parse"));
|
|
13
|
+
|
|
14
|
+
var _url = require("./url");
|
|
15
|
+
|
|
16
|
+
var _config = require("../config");
|
|
17
|
+
|
|
18
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
19
|
+
|
|
20
|
+
function isValidResponse(xhr) {
|
|
21
|
+
return isValidContent(xhr) && !downloadingFile(xhr);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function isValidContent(rsp) {
|
|
25
|
+
var contentType = rsp.headers.get('content-type');
|
|
26
|
+
var jsContent = /^(?:application\/json)(?:;|$)/;
|
|
27
|
+
return !!(contentType !== undefined && contentType.match(jsContent));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function downloadingFile(xhr) {
|
|
31
|
+
var disposition = xhr.headers.get('content-disposition');
|
|
32
|
+
return disposition !== undefined && disposition !== null && disposition.match(/^attachment/);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function validateResponse(args) {
|
|
36
|
+
var rsp = args.rsp;
|
|
37
|
+
|
|
38
|
+
if (isValidResponse(rsp)) {
|
|
39
|
+
return args;
|
|
40
|
+
} else {
|
|
41
|
+
var error = new Error('Invalid Superglue Response');
|
|
42
|
+
error.response = rsp;
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function handleServerErrors(args) {
|
|
48
|
+
var rsp = args.rsp;
|
|
49
|
+
|
|
50
|
+
if (!rsp.ok) {
|
|
51
|
+
var error = new Error(rsp.statusText);
|
|
52
|
+
error.response = rsp;
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return args;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function argsForFetch(getState, pathQuery, _temp) {
|
|
60
|
+
var _ref = _temp === void 0 ? {} : _temp,
|
|
61
|
+
_ref$method = _ref.method,
|
|
62
|
+
method = _ref$method === void 0 ? 'GET' : _ref$method,
|
|
63
|
+
_ref$headers = _ref.headers,
|
|
64
|
+
headers = _ref$headers === void 0 ? {} : _ref$headers,
|
|
65
|
+
_ref$body = _ref.body,
|
|
66
|
+
body = _ref$body === void 0 ? '' : _ref$body,
|
|
67
|
+
signal = _ref.signal;
|
|
68
|
+
|
|
69
|
+
method = method.toUpperCase();
|
|
70
|
+
var currentState = getState().superglue || {};
|
|
71
|
+
var jsAccept = 'application/json';
|
|
72
|
+
headers = Object.assign({}, headers, {
|
|
73
|
+
accept: jsAccept,
|
|
74
|
+
'x-requested-with': 'XMLHttpRequest',
|
|
75
|
+
'x-superglue-request': true
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (method != 'GET' && method != 'HEAD') {
|
|
79
|
+
if (headers['content-type'] === null) {
|
|
80
|
+
delete headers['content-type'];
|
|
81
|
+
} else {
|
|
82
|
+
headers['content-type'] = 'application/json';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (currentState.csrfToken) {
|
|
87
|
+
headers['x-csrf-token'] = currentState.csrfToken;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
var href = new _urlParse["default"](pathQuery, _config.config.baseUrl || {}, false).href;
|
|
91
|
+
var credentials = 'same-origin';
|
|
92
|
+
|
|
93
|
+
if (!(method == 'GET' || method == 'HEAD')) {
|
|
94
|
+
headers['x-http-method-override'] = method;
|
|
95
|
+
method = 'POST';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
var options = {
|
|
99
|
+
method: method,
|
|
100
|
+
headers: headers,
|
|
101
|
+
body: body,
|
|
102
|
+
credentials: credentials,
|
|
103
|
+
signal: signal
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
if (currentState.currentPageKey) {
|
|
107
|
+
var referrer = new _urlParse["default"](currentState.currentPageKey, _config.config.baseUrl || {}, false).href;
|
|
108
|
+
options.referrer = referrer;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (method == 'GET' || method == 'HEAD') {
|
|
112
|
+
delete options.body;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return [(0, _url.formatForXHR)(href), options];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function extractJSON(rsp) {
|
|
119
|
+
return rsp.json().then(function (json) {
|
|
120
|
+
return {
|
|
121
|
+
rsp: rsp,
|
|
122
|
+
json: json
|
|
123
|
+
};
|
|
124
|
+
})["catch"](function (e) {
|
|
125
|
+
e.response = rsp;
|
|
126
|
+
throw e;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function parseResponse(prm) {
|
|
131
|
+
return Promise.resolve(prm).then(extractJSON).then(handleServerErrors).then(validateResponse);
|
|
132
|
+
}
|
package/utils/ujs.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.ujsHandlers = exports.HandlerBuilder = void 0;
|
|
5
|
+
|
|
6
|
+
var _url = require("./url");
|
|
7
|
+
|
|
8
|
+
var HandlerBuilder = /*#__PURE__*/function () {
|
|
9
|
+
function HandlerBuilder(_ref) {
|
|
10
|
+
var ujsAttributePrefix = _ref.ujsAttributePrefix,
|
|
11
|
+
visit = _ref.visit,
|
|
12
|
+
remote = _ref.remote;
|
|
13
|
+
this.attributePrefix = ujsAttributePrefix;
|
|
14
|
+
this.isUJS = this.isUJS.bind(this);
|
|
15
|
+
this.handleSubmit = this.handleSubmit.bind(this);
|
|
16
|
+
this.handleClick = this.handleClick.bind(this);
|
|
17
|
+
this.visit = visit;
|
|
18
|
+
this.remote = remote;
|
|
19
|
+
this.visitOrRemote = this.visitOrRemote.bind(this);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
var _proto = HandlerBuilder.prototype;
|
|
23
|
+
|
|
24
|
+
_proto.retrieveLink = function retrieveLink(target) {
|
|
25
|
+
var link = target;
|
|
26
|
+
|
|
27
|
+
while (!!link.parentNode && link.nodeName.toLowerCase() !== 'a') {
|
|
28
|
+
link = link.parentNode;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (link.nodeName.toLowerCase() === 'a' && link.href.length !== 0) {
|
|
32
|
+
return link;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
_proto.isNonStandardClick = function isNonStandardClick(event) {
|
|
37
|
+
return event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
_proto.isUJS = function isUJS(node) {
|
|
41
|
+
var hasVisit = !!node.getAttribute(this.attributePrefix + '-visit');
|
|
42
|
+
var hasRemote = !!node.getAttribute(this.attributePrefix + '-remote');
|
|
43
|
+
return hasVisit || hasRemote;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
_proto.handleSubmit = function handleSubmit(event) {
|
|
47
|
+
var form = event.target;
|
|
48
|
+
|
|
49
|
+
if (form.nodeName.toLowerCase() !== 'form' || !this.isUJS(form)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
event.preventDefault();
|
|
54
|
+
var url = form.getAttribute('action');
|
|
55
|
+
var method = (form.getAttribute('method') || 'POST').toUpperCase();
|
|
56
|
+
url = (0, _url.withoutBusters)(url);
|
|
57
|
+
this.visitOrRemote(form, url, {
|
|
58
|
+
method: method,
|
|
59
|
+
headers: {
|
|
60
|
+
'content-type': null
|
|
61
|
+
},
|
|
62
|
+
body: new FormData(event.target)
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
_proto.handleClick = function handleClick(event) {
|
|
67
|
+
var link = this.retrieveLink(event.target);
|
|
68
|
+
var isNonStandard = this.isNonStandardClick(event);
|
|
69
|
+
|
|
70
|
+
if (!link || isNonStandard || !this.isUJS(link)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
var url = link.getAttribute('href');
|
|
76
|
+
url = (0, _url.withoutBusters)(url);
|
|
77
|
+
var method = link.getAttribute(this.attributePrefix + '-method') || 'GET';
|
|
78
|
+
this.visitOrRemote(link, url, {
|
|
79
|
+
method: method
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
_proto.visitOrRemote = function visitOrRemote(linkOrForm, url, opts) {
|
|
84
|
+
if (opts === void 0) {
|
|
85
|
+
opts = {};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
var target;
|
|
89
|
+
|
|
90
|
+
if (linkOrForm.getAttribute(this.attributePrefix + '-visit')) {
|
|
91
|
+
target = this.visit;
|
|
92
|
+
var placeholderKey = linkOrForm.getAttribute(this.attributePrefix + '-placeholder');
|
|
93
|
+
|
|
94
|
+
if (placeholderKey) {
|
|
95
|
+
opts.placeholderKey = (0, _url.urlToPageKey)(placeholderKey);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (linkOrForm.getAttribute(this.attributePrefix + '-remote')) {
|
|
100
|
+
target = this.remote;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (!target) {
|
|
104
|
+
return;
|
|
105
|
+
} else {
|
|
106
|
+
return target(url, opts);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
_proto.handlers = function handlers() {
|
|
111
|
+
return {
|
|
112
|
+
onClick: this.handleClick,
|
|
113
|
+
onSubmit: this.handleSubmit
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
return HandlerBuilder;
|
|
118
|
+
}();
|
|
119
|
+
|
|
120
|
+
exports.HandlerBuilder = HandlerBuilder;
|
|
121
|
+
|
|
122
|
+
var ujsHandlers = function ujsHandlers(_ref2) {
|
|
123
|
+
var navigatorRef = _ref2.navigatorRef,
|
|
124
|
+
store = _ref2.store,
|
|
125
|
+
ujsAttributePrefix = _ref2.ujsAttributePrefix,
|
|
126
|
+
visit = _ref2.visit,
|
|
127
|
+
remote = _ref2.remote;
|
|
128
|
+
var builder = new HandlerBuilder({
|
|
129
|
+
navigatorRef: navigatorRef,
|
|
130
|
+
store: store,
|
|
131
|
+
visit: visit,
|
|
132
|
+
remote: remote,
|
|
133
|
+
ujsAttributePrefix: ujsAttributePrefix
|
|
134
|
+
});
|
|
135
|
+
return builder.handlers();
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
exports.ujsHandlers = ujsHandlers;
|
package/utils/url.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.formatForXHR = formatForXHR;
|
|
5
|
+
exports.hasPropsAt = hasPropsAt;
|
|
6
|
+
exports.pathQuery = pathQuery;
|
|
7
|
+
exports.pathQueryHash = pathQueryHash;
|
|
8
|
+
exports.pathWithoutBZParams = pathWithoutBZParams;
|
|
9
|
+
exports.removePropsAt = removePropsAt;
|
|
10
|
+
exports.urlToPageKey = urlToPageKey;
|
|
11
|
+
exports.withAntiCache = withAntiCache;
|
|
12
|
+
exports.withMimeBust = withMimeBust;
|
|
13
|
+
exports.withoutBusters = withoutBusters;
|
|
14
|
+
exports.withoutHash = withoutHash;
|
|
15
|
+
|
|
16
|
+
var _urlParse = _interopRequireDefault(require("url-parse"));
|
|
17
|
+
|
|
18
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
19
|
+
|
|
20
|
+
var uniqueId = function uniqueId() {
|
|
21
|
+
return Math.random().toString(36).substring(2, 10);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
function pathQuery(url) {
|
|
25
|
+
var _parse = new _urlParse["default"](url, {}),
|
|
26
|
+
pathname = _parse.pathname,
|
|
27
|
+
query = _parse.query;
|
|
28
|
+
|
|
29
|
+
return pathname + query;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function pathQueryHash(url) {
|
|
33
|
+
var _parse2 = new _urlParse["default"](url, {}),
|
|
34
|
+
pathname = _parse2.pathname,
|
|
35
|
+
query = _parse2.query,
|
|
36
|
+
hash = _parse2.hash;
|
|
37
|
+
|
|
38
|
+
return pathname + query + hash;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function hasPropsAt(url) {
|
|
42
|
+
url = new _urlParse["default"](url, {}, true);
|
|
43
|
+
var query = url.query;
|
|
44
|
+
return !!query['props_at'];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function withAntiCache(url) {
|
|
48
|
+
url = new _urlParse["default"](url, {}, true);
|
|
49
|
+
|
|
50
|
+
if (Object.prototype.hasOwnProperty.call(url.query, '_')) {
|
|
51
|
+
return url.toString();
|
|
52
|
+
} else {
|
|
53
|
+
url.query['_'] = uniqueId();
|
|
54
|
+
return url.toString();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function withMimeBust(url) {
|
|
59
|
+
url = new _urlParse["default"](url, {}, true);
|
|
60
|
+
|
|
61
|
+
if (Object.prototype.hasOwnProperty.call(url.query, '__')) {
|
|
62
|
+
return url.toString();
|
|
63
|
+
} else {
|
|
64
|
+
url.query['__'] = '0';
|
|
65
|
+
return url.toString();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function withoutBusters(url) {
|
|
70
|
+
url = new _urlParse["default"](url, {}, true);
|
|
71
|
+
var query = url.query;
|
|
72
|
+
delete query['__'];
|
|
73
|
+
delete query['_'];
|
|
74
|
+
url.query = query;
|
|
75
|
+
return pathQuery(url.toString());
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function pathWithoutBZParams(url) {
|
|
79
|
+
url = new _urlParse["default"](url, {}, true);
|
|
80
|
+
var query = url.query;
|
|
81
|
+
delete query['__'];
|
|
82
|
+
delete query['_'];
|
|
83
|
+
delete query['props_at'];
|
|
84
|
+
url.query = query;
|
|
85
|
+
return pathQueryHash(url.toString());
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function removePropsAt(url) {
|
|
89
|
+
url = new _urlParse["default"](url, {}, true);
|
|
90
|
+
var query = url.query;
|
|
91
|
+
delete query['props_at'];
|
|
92
|
+
url.query = query;
|
|
93
|
+
return url.toString();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function urlToPageKey(url) {
|
|
97
|
+
url = new _urlParse["default"](url, {}, true);
|
|
98
|
+
var query = url.query;
|
|
99
|
+
delete query['__'];
|
|
100
|
+
delete query['_'];
|
|
101
|
+
delete query['props_at'];
|
|
102
|
+
url.query = query;
|
|
103
|
+
return pathQuery(url.toString());
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function withoutHash(url) {
|
|
107
|
+
url = new _urlParse["default"](url, {}, true);
|
|
108
|
+
url.hash = '';
|
|
109
|
+
return url.toString();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function formatForXHR(url, opts) {
|
|
113
|
+
if (opts === void 0) {
|
|
114
|
+
opts = {};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
var formats = [withMimeBust, withoutHash];
|
|
118
|
+
|
|
119
|
+
if (opts.cacheRequest) {
|
|
120
|
+
formats.push(withAntiCache);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return formats.reduce(function (memo, f) {
|
|
124
|
+
return f(memo);
|
|
125
|
+
}, url);
|
|
126
|
+
}
|
package/utils/window.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.needsRefresh = needsRefresh;
|
|
5
|
+
|
|
6
|
+
function needsRefresh(prevAssets, newAssets) {
|
|
7
|
+
if (prevAssets && newAssets) {
|
|
8
|
+
var hasNewAssets = !newAssets.every(function (asset) {
|
|
9
|
+
return prevAssets.includes(asset);
|
|
10
|
+
});
|
|
11
|
+
return hasNewAssets;
|
|
12
|
+
} else {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|