@kineticdata/react 6.1.6 → 7.0.0-rc1
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/lib/apis/core/authentication.js +241 -67
- package/lib/apis/core/authentication.test.js +360 -0
- package/lib/apis/core/customIndexes.js +102 -0
- package/lib/apis/core/customIndexes.test.js +276 -0
- package/lib/apis/core/oauthClients.js +33 -8
- package/lib/apis/index.js +12 -0
- package/lib/components/core/custom_index/CustomIndexForm.js +140 -0
- package/lib/components/core/custom_index/CustomIndexTable.js +98 -0
- package/lib/components/core/oauth_client/OAuthClientForm.js +246 -28
- package/lib/components/core/oauth_client/OAuthClientTable.js +77 -8
- package/lib/components/index.js +14 -0
- package/lib/helpers/index.js +6 -1
- package/package.json +5 -5
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
|
4
|
+
var _regeneratorRuntime2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/regeneratorRuntime"));
|
|
5
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/asyncToGenerator"));
|
|
6
|
+
var _util = require("util");
|
|
7
|
+
var _axios = _interopRequireDefault(require("axios"));
|
|
8
|
+
var _authentication = require("./authentication");
|
|
9
|
+
// Polyfill TextEncoder for jsdom environment
|
|
10
|
+
global.TextEncoder = _util.TextEncoder;
|
|
11
|
+
jest.mock('../../helpers', function () {
|
|
12
|
+
return {
|
|
13
|
+
bundle: {
|
|
14
|
+
spaceLocation: function spaceLocation() {
|
|
15
|
+
return 'https://test.kinetic.com/space';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
jest.mock('./profile', function () {
|
|
21
|
+
return {
|
|
22
|
+
fetchProfile: jest.fn()
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Simulates the hidden iframe flow used by attemptAuthorize.
|
|
28
|
+
*
|
|
29
|
+
* @param {string|Function} hrefOrFn - Either a static href string the iframe
|
|
30
|
+
* will "navigate" to, or a function called on each load that returns the href.
|
|
31
|
+
*/
|
|
32
|
+
function installIframeTrap(hrefOrFn) {
|
|
33
|
+
var origCreate = document.createElement.bind(document);
|
|
34
|
+
jest.spyOn(document, 'createElement').mockImplementation(function (tag) {
|
|
35
|
+
if (tag !== 'iframe') return origCreate(tag);
|
|
36
|
+
var iframe = origCreate('iframe');
|
|
37
|
+
var srcValue;
|
|
38
|
+
Object.defineProperty(iframe, 'src', {
|
|
39
|
+
get: function get() {
|
|
40
|
+
return srcValue;
|
|
41
|
+
},
|
|
42
|
+
set: function set(val) {
|
|
43
|
+
srcValue = val;
|
|
44
|
+
// Simulate async load on next microtask
|
|
45
|
+
Promise.resolve().then(function () {
|
|
46
|
+
var href = typeof hrefOrFn === 'function' ? hrefOrFn() : hrefOrFn;
|
|
47
|
+
Object.defineProperty(iframe, 'contentWindow', {
|
|
48
|
+
value: {
|
|
49
|
+
location: {
|
|
50
|
+
href: href
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
configurable: true
|
|
54
|
+
});
|
|
55
|
+
if (iframe.onload) iframe.onload();
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return iframe;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Like installIframeTrap but the first onload triggers a cross-origin error
|
|
65
|
+
* before a second onload resolves with the given href.
|
|
66
|
+
*/
|
|
67
|
+
function installCrossOriginIframeTrap(successHref) {
|
|
68
|
+
var origCreate = document.createElement.bind(document);
|
|
69
|
+
var loadCount = 0;
|
|
70
|
+
jest.spyOn(document, 'createElement').mockImplementation(function (tag) {
|
|
71
|
+
if (tag !== 'iframe') return origCreate(tag);
|
|
72
|
+
var iframe = origCreate('iframe');
|
|
73
|
+
var srcValue;
|
|
74
|
+
Object.defineProperty(iframe, 'src', {
|
|
75
|
+
get: function get() {
|
|
76
|
+
return srcValue;
|
|
77
|
+
},
|
|
78
|
+
set: function set(val) {
|
|
79
|
+
srcValue = val;
|
|
80
|
+
Promise.resolve().then(function () {
|
|
81
|
+
loadCount++;
|
|
82
|
+
if (loadCount === 1) {
|
|
83
|
+
Object.defineProperty(iframe, 'contentWindow', {
|
|
84
|
+
get: function get() {
|
|
85
|
+
throw new DOMException('Blocked a frame');
|
|
86
|
+
},
|
|
87
|
+
configurable: true
|
|
88
|
+
});
|
|
89
|
+
if (iframe.onload) iframe.onload();
|
|
90
|
+
|
|
91
|
+
// Fire a second load with the successful response
|
|
92
|
+
Promise.resolve().then(function () {
|
|
93
|
+
Object.defineProperty(iframe, 'contentWindow', {
|
|
94
|
+
value: {
|
|
95
|
+
location: {
|
|
96
|
+
href: successHref
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
configurable: true
|
|
100
|
+
});
|
|
101
|
+
if (iframe.onload) iframe.onload();
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return iframe;
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
describe('authentication api', function () {
|
|
111
|
+
var savedCrypto;
|
|
112
|
+
beforeAll(function () {
|
|
113
|
+
savedCrypto = global.crypto;
|
|
114
|
+
Object.defineProperty(global, 'crypto', {
|
|
115
|
+
value: {
|
|
116
|
+
getRandomValues: jest.fn(function (array) {
|
|
117
|
+
array.fill(0);
|
|
118
|
+
return array;
|
|
119
|
+
}),
|
|
120
|
+
subtle: {
|
|
121
|
+
digest: jest.fn(function () {
|
|
122
|
+
return Promise.resolve(new Uint8Array(32).buffer);
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
writable: true
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
afterAll(function () {
|
|
130
|
+
Object.defineProperty(global, 'crypto', {
|
|
131
|
+
value: savedCrypto,
|
|
132
|
+
writable: true
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
afterEach(function () {
|
|
136
|
+
jest.restoreAllMocks();
|
|
137
|
+
});
|
|
138
|
+
describe('#login', function () {
|
|
139
|
+
test('posts credentials to the login endpoint', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee() {
|
|
140
|
+
return (0, _regeneratorRuntime2["default"])().wrap(function _callee$(_context) {
|
|
141
|
+
while (1) switch (_context.prev = _context.next) {
|
|
142
|
+
case 0:
|
|
143
|
+
_axios["default"].post = jest.fn(function () {
|
|
144
|
+
return Promise.resolve({
|
|
145
|
+
status: 200,
|
|
146
|
+
data: {}
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
_context.next = 3;
|
|
150
|
+
return (0, _authentication.login)({
|
|
151
|
+
username: 'admin',
|
|
152
|
+
password: 'secret'
|
|
153
|
+
});
|
|
154
|
+
case 3:
|
|
155
|
+
expect(_axios["default"].post).toHaveBeenCalledWith('https://test.kinetic.com/space/app/login.do', {
|
|
156
|
+
j_username: 'admin',
|
|
157
|
+
j_password: 'secret'
|
|
158
|
+
}, {
|
|
159
|
+
__bypassAuthInterceptor: true
|
|
160
|
+
});
|
|
161
|
+
case 4:
|
|
162
|
+
case "end":
|
|
163
|
+
return _context.stop();
|
|
164
|
+
}
|
|
165
|
+
}, _callee);
|
|
166
|
+
})));
|
|
167
|
+
});
|
|
168
|
+
describe('#logoutDirect', function () {
|
|
169
|
+
test('uses the standard logout endpoint', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee2() {
|
|
170
|
+
return (0, _regeneratorRuntime2["default"])().wrap(function _callee2$(_context2) {
|
|
171
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
172
|
+
case 0:
|
|
173
|
+
_axios["default"].get = jest.fn(function () {
|
|
174
|
+
return Promise.resolve({
|
|
175
|
+
status: 200
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
_context2.next = 3;
|
|
179
|
+
return (0, _authentication.logoutDirect)(false);
|
|
180
|
+
case 3:
|
|
181
|
+
expect(_axios["default"].get).toHaveBeenCalledWith('https://test.kinetic.com/space/app/logout');
|
|
182
|
+
case 4:
|
|
183
|
+
case "end":
|
|
184
|
+
return _context2.stop();
|
|
185
|
+
}
|
|
186
|
+
}, _callee2);
|
|
187
|
+
})));
|
|
188
|
+
test('uses the SAML logout endpoint when isSaml is true', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee3() {
|
|
189
|
+
return (0, _regeneratorRuntime2["default"])().wrap(function _callee3$(_context3) {
|
|
190
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
191
|
+
case 0:
|
|
192
|
+
_axios["default"].get = jest.fn(function () {
|
|
193
|
+
return Promise.resolve({
|
|
194
|
+
status: 200
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
_context3.next = 3;
|
|
198
|
+
return (0, _authentication.logoutDirect)(true);
|
|
199
|
+
case 3:
|
|
200
|
+
expect(_axios["default"].get).toHaveBeenCalledWith('https://test.kinetic.com/space/app/saml2/logout');
|
|
201
|
+
case 4:
|
|
202
|
+
case "end":
|
|
203
|
+
return _context3.stop();
|
|
204
|
+
}
|
|
205
|
+
}, _callee3);
|
|
206
|
+
})));
|
|
207
|
+
});
|
|
208
|
+
describe('#retrieveJwt', function () {
|
|
209
|
+
test('returns the access token on success', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee4() {
|
|
210
|
+
var fakeToken, token, params;
|
|
211
|
+
return (0, _regeneratorRuntime2["default"])().wrap(function _callee4$(_context4) {
|
|
212
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
213
|
+
case 0:
|
|
214
|
+
fakeToken = 'jwt-token-123';
|
|
215
|
+
_axios["default"].post = jest.fn(function () {
|
|
216
|
+
return Promise.resolve({
|
|
217
|
+
data: {
|
|
218
|
+
access_token: fakeToken
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
installIframeTrap("".concat(window.location.origin, "/app/oauth/callback?code=auth-code-xyz"));
|
|
223
|
+
_context4.next = 5;
|
|
224
|
+
return (0, _authentication.retrieveJwt)();
|
|
225
|
+
case 5:
|
|
226
|
+
token = _context4.sent;
|
|
227
|
+
expect(token).toBe(fakeToken);
|
|
228
|
+
expect(_axios["default"].post).toHaveBeenCalledWith('https://test.kinetic.com/space/app/oauth2/token', expect.any(URLSearchParams), expect.objectContaining({
|
|
229
|
+
headers: {
|
|
230
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
231
|
+
},
|
|
232
|
+
__bypassAuthInterceptor: true,
|
|
233
|
+
__bypassInitInterceptor: true
|
|
234
|
+
}));
|
|
235
|
+
params = _axios["default"].post.mock.calls[0][1];
|
|
236
|
+
expect(params.get('grant_type')).toBe('authorization_code');
|
|
237
|
+
expect(params.get('code')).toBe('auth-code-xyz');
|
|
238
|
+
expect(params.get('redirect_uri')).toContain('/app/oauth/callback');
|
|
239
|
+
case 12:
|
|
240
|
+
case "end":
|
|
241
|
+
return _context4.stop();
|
|
242
|
+
}
|
|
243
|
+
}, _callee4);
|
|
244
|
+
})));
|
|
245
|
+
test('returns undefined when the user is unauthenticated', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee5() {
|
|
246
|
+
var token;
|
|
247
|
+
return (0, _regeneratorRuntime2["default"])().wrap(function _callee5$(_context5) {
|
|
248
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
249
|
+
case 0:
|
|
250
|
+
installIframeTrap('https://test.kinetic.com/space/app/login');
|
|
251
|
+
_context5.next = 3;
|
|
252
|
+
return (0, _authentication.retrieveJwt)();
|
|
253
|
+
case 3:
|
|
254
|
+
token = _context5.sent;
|
|
255
|
+
expect(token).toBeUndefined();
|
|
256
|
+
case 5:
|
|
257
|
+
case "end":
|
|
258
|
+
return _context5.stop();
|
|
259
|
+
}
|
|
260
|
+
}, _callee5);
|
|
261
|
+
})));
|
|
262
|
+
test('returns undefined on OAuth error', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee6() {
|
|
263
|
+
var token;
|
|
264
|
+
return (0, _regeneratorRuntime2["default"])().wrap(function _callee6$(_context6) {
|
|
265
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
266
|
+
case 0:
|
|
267
|
+
installIframeTrap("".concat(window.location.origin, "/app/oauth/callback?error=server_error"));
|
|
268
|
+
_context6.next = 3;
|
|
269
|
+
return (0, _authentication.retrieveJwt)();
|
|
270
|
+
case 3:
|
|
271
|
+
token = _context6.sent;
|
|
272
|
+
expect(token).toBeUndefined();
|
|
273
|
+
case 5:
|
|
274
|
+
case "end":
|
|
275
|
+
return _context6.stop();
|
|
276
|
+
}
|
|
277
|
+
}, _callee6);
|
|
278
|
+
})));
|
|
279
|
+
test('returns undefined when token exchange fails', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee7() {
|
|
280
|
+
var token;
|
|
281
|
+
return (0, _regeneratorRuntime2["default"])().wrap(function _callee7$(_context7) {
|
|
282
|
+
while (1) switch (_context7.prev = _context7.next) {
|
|
283
|
+
case 0:
|
|
284
|
+
installIframeTrap("".concat(window.location.origin, "/app/oauth/callback?code=some-code"));
|
|
285
|
+
_axios["default"].post = jest.fn(function () {
|
|
286
|
+
return Promise.reject(new Error('network error'));
|
|
287
|
+
});
|
|
288
|
+
jest.spyOn(console, 'error').mockImplementation(function () {});
|
|
289
|
+
_context7.next = 5;
|
|
290
|
+
return (0, _authentication.retrieveJwt)();
|
|
291
|
+
case 5:
|
|
292
|
+
token = _context7.sent;
|
|
293
|
+
expect(token).toBeUndefined();
|
|
294
|
+
case 7:
|
|
295
|
+
case "end":
|
|
296
|
+
return _context7.stop();
|
|
297
|
+
}
|
|
298
|
+
}, _callee7);
|
|
299
|
+
})));
|
|
300
|
+
test('returns undefined when authorization times out', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee8() {
|
|
301
|
+
var origCreate, promise, token;
|
|
302
|
+
return (0, _regeneratorRuntime2["default"])().wrap(function _callee8$(_context8) {
|
|
303
|
+
while (1) switch (_context8.prev = _context8.next) {
|
|
304
|
+
case 0:
|
|
305
|
+
jest.useFakeTimers();
|
|
306
|
+
jest.spyOn(console, 'error').mockImplementation(function () {});
|
|
307
|
+
|
|
308
|
+
// Install an iframe trap that never fires onload
|
|
309
|
+
origCreate = document.createElement.bind(document);
|
|
310
|
+
jest.spyOn(document, 'createElement').mockImplementation(function (tag) {
|
|
311
|
+
if (tag !== 'iframe') return origCreate(tag);
|
|
312
|
+
var iframe = origCreate('iframe');
|
|
313
|
+
Object.defineProperty(iframe, 'src', {
|
|
314
|
+
get: function get() {
|
|
315
|
+
return '';
|
|
316
|
+
},
|
|
317
|
+
set: function set() {}
|
|
318
|
+
});
|
|
319
|
+
return iframe;
|
|
320
|
+
});
|
|
321
|
+
promise = (0, _authentication.retrieveJwt)();
|
|
322
|
+
jest.advanceTimersByTime(15000);
|
|
323
|
+
_context8.next = 8;
|
|
324
|
+
return promise;
|
|
325
|
+
case 8:
|
|
326
|
+
token = _context8.sent;
|
|
327
|
+
expect(token).toBeUndefined();
|
|
328
|
+
jest.useRealTimers();
|
|
329
|
+
case 11:
|
|
330
|
+
case "end":
|
|
331
|
+
return _context8.stop();
|
|
332
|
+
}
|
|
333
|
+
}, _callee8);
|
|
334
|
+
})));
|
|
335
|
+
test('handles cross-origin iframe errors gracefully during redirects', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee9() {
|
|
336
|
+
var token;
|
|
337
|
+
return (0, _regeneratorRuntime2["default"])().wrap(function _callee9$(_context9) {
|
|
338
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
339
|
+
case 0:
|
|
340
|
+
installCrossOriginIframeTrap("".concat(window.location.origin, "/app/oauth/callback?code=final-code"));
|
|
341
|
+
_axios["default"].post = jest.fn(function () {
|
|
342
|
+
return Promise.resolve({
|
|
343
|
+
data: {
|
|
344
|
+
access_token: 'cross-origin-token'
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
_context9.next = 4;
|
|
349
|
+
return (0, _authentication.retrieveJwt)();
|
|
350
|
+
case 4:
|
|
351
|
+
token = _context9.sent;
|
|
352
|
+
expect(token).toBe('cross-origin-token');
|
|
353
|
+
case 6:
|
|
354
|
+
case "end":
|
|
355
|
+
return _context9.stop();
|
|
356
|
+
}
|
|
357
|
+
}, _callee9);
|
|
358
|
+
})));
|
|
359
|
+
});
|
|
360
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.fetchCustomIndexes = exports.deleteCustomIndex = exports.createCustomIndex = void 0;
|
|
8
|
+
var _axios = _interopRequireDefault(require("axios"));
|
|
9
|
+
var _helpers = require("../../helpers");
|
|
10
|
+
var _http = require("../http");
|
|
11
|
+
var indexesUrl = function indexesUrl(_ref) {
|
|
12
|
+
var kappSlug = _ref.kappSlug,
|
|
13
|
+
formSlug = _ref.formSlug;
|
|
14
|
+
return "".concat(_helpers.bundle.apiLocation(), "/kapps/").concat(encodeURIComponent(kappSlug), "/forms/").concat(encodeURIComponent(formSlug), "/indexes");
|
|
15
|
+
};
|
|
16
|
+
var indexUrl = function indexUrl(_ref2) {
|
|
17
|
+
var kappSlug = _ref2.kappSlug,
|
|
18
|
+
formSlug = _ref2.formSlug,
|
|
19
|
+
indexName = _ref2.indexName;
|
|
20
|
+
return "".concat(indexesUrl({
|
|
21
|
+
kappSlug: kappSlug,
|
|
22
|
+
formSlug: formSlug
|
|
23
|
+
}), "/").concat(encodeURIComponent(indexName));
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// `key` is server-populated on response and ignored on request. Strip it
|
|
27
|
+
// defensively in case a caller round-trips a fetched index back into create.
|
|
28
|
+
var sanitizePart = function sanitizePart(part) {
|
|
29
|
+
return {
|
|
30
|
+
type: part.type,
|
|
31
|
+
name: part.name
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Fetches all custom Postgres indexes defined on a form.
|
|
37
|
+
*
|
|
38
|
+
* @param {Object} options
|
|
39
|
+
* @param {string} options.kappSlug
|
|
40
|
+
* @param {string} options.formSlug
|
|
41
|
+
* @returns {Promise<{indexes: Object[]}>}
|
|
42
|
+
*/
|
|
43
|
+
var fetchCustomIndexes = exports.fetchCustomIndexes = function fetchCustomIndexes() {
|
|
44
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
45
|
+
(0, _http.validateOptions)('fetchCustomIndexes', ['kappSlug', 'formSlug'], options);
|
|
46
|
+
return _axios["default"].get(indexesUrl(options), {
|
|
47
|
+
params: (0, _http.paramBuilder)(options),
|
|
48
|
+
headers: (0, _http.headerBuilder)(options)
|
|
49
|
+
}).then(function (response) {
|
|
50
|
+
return {
|
|
51
|
+
indexes: response.data.indexes
|
|
52
|
+
};
|
|
53
|
+
})["catch"](_http.handleErrors);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Creates a custom Postgres index on a form's submissions.
|
|
58
|
+
*
|
|
59
|
+
* @param {Object} options
|
|
60
|
+
* @param {string} options.kappSlug
|
|
61
|
+
* @param {string} options.formSlug
|
|
62
|
+
* @param {{name: string, unique?: boolean, parts: Array<{type: 'value'|'property', name: string}>}} options.index
|
|
63
|
+
* @returns {Promise<{index: Object}|{error: Object}>}
|
|
64
|
+
*/
|
|
65
|
+
var createCustomIndex = exports.createCustomIndex = function createCustomIndex() {
|
|
66
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
67
|
+
(0, _http.validateOptions)('createCustomIndex', ['kappSlug', 'formSlug', 'index'], options);
|
|
68
|
+
var index = options.index;
|
|
69
|
+
var payload = {
|
|
70
|
+
name: index.name,
|
|
71
|
+
unique: !!index.unique,
|
|
72
|
+
parts: (index.parts || []).map(sanitizePart)
|
|
73
|
+
};
|
|
74
|
+
return _axios["default"].post(indexesUrl(options), payload, {
|
|
75
|
+
params: (0, _http.paramBuilder)(options),
|
|
76
|
+
headers: (0, _http.headerBuilder)(options)
|
|
77
|
+
}).then(function (response) {
|
|
78
|
+
return {
|
|
79
|
+
index: response.data.index
|
|
80
|
+
};
|
|
81
|
+
})["catch"](_http.handleErrors);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Drops a custom Postgres index by name.
|
|
86
|
+
*
|
|
87
|
+
* @param {Object} options
|
|
88
|
+
* @param {string} options.kappSlug
|
|
89
|
+
* @param {string} options.formSlug
|
|
90
|
+
* @param {string} options.indexName
|
|
91
|
+
* @returns {Promise<{}|{error: Object}>}
|
|
92
|
+
*/
|
|
93
|
+
var deleteCustomIndex = exports.deleteCustomIndex = function deleteCustomIndex() {
|
|
94
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
95
|
+
(0, _http.validateOptions)('deleteCustomIndex', ['kappSlug', 'formSlug', 'indexName'], options);
|
|
96
|
+
return _axios["default"]["delete"](indexUrl(options), {
|
|
97
|
+
params: (0, _http.paramBuilder)(options),
|
|
98
|
+
headers: (0, _http.headerBuilder)(options)
|
|
99
|
+
}).then(function () {
|
|
100
|
+
return {};
|
|
101
|
+
})["catch"](_http.handleErrors);
|
|
102
|
+
};
|