@looker/sdk-rtl 21.5.0 → 21.6.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/CHANGELOG.md +7 -0
- package/lib/CSRFSession.js +3 -17
- package/lib/CSRFSession.js.map +1 -1
- package/lib/apiMethods.js +6 -47
- package/lib/apiMethods.js.map +1 -1
- package/lib/apiSettings.js +4 -24
- package/lib/apiSettings.js.map +1 -1
- package/lib/authSession.js +3 -18
- package/lib/authSession.js.map +1 -1
- package/lib/authToken.js +3 -18
- package/lib/authToken.js.map +1 -1
- package/lib/baseTransport.js +3 -12
- package/lib/baseTransport.js.map +1 -1
- package/lib/browser.js +0 -34
- package/lib/browser.js.map +1 -1
- package/lib/browserServices.js +3 -11
- package/lib/browserServices.js.map +1 -1
- package/lib/browserSession.js +6 -21
- package/lib/browserSession.js.map +1 -1
- package/lib/browserTransport.js +5 -63
- package/lib/browserTransport.js.map +1 -1
- package/lib/constants.js +1 -11
- package/lib/constants.js.map +1 -1
- package/lib/cryptoHash.js +1 -1
- package/lib/cryptoHash.js.map +1 -1
- package/lib/delimArray.js +3 -8
- package/lib/delimArray.js.map +1 -1
- package/lib/errorDoc.js +8 -49
- package/lib/errorDoc.js.map +1 -1
- package/lib/esm/CSRFSession.js +14 -17
- package/lib/esm/CSRFSession.js.map +1 -1
- package/lib/esm/apiMethods.js +18 -46
- package/lib/esm/apiMethods.js.map +1 -1
- package/lib/esm/apiSettings.js +32 -28
- package/lib/esm/apiSettings.js.map +1 -1
- package/lib/esm/authSession.js +14 -19
- package/lib/esm/authSession.js.map +1 -1
- package/lib/esm/authToken.js +11 -17
- package/lib/esm/authToken.js.map +1 -1
- package/lib/esm/baseTransport.js +14 -13
- package/lib/esm/baseTransport.js.map +1 -1
- package/lib/esm/browser.js +192 -17
- package/lib/esm/browser.js.map +1 -1
- package/lib/esm/browserServices.js +15 -12
- package/lib/esm/browserServices.js.map +1 -1
- package/lib/esm/browserSession.js +21 -23
- package/lib/esm/browserSession.js.map +1 -1
- package/lib/esm/browserTransport.js +24 -68
- package/lib/esm/browserTransport.js.map +1 -1
- package/lib/esm/constants.js +22 -10
- package/lib/esm/constants.js.map +1 -1
- package/lib/esm/cryptoHash.js.map +1 -1
- package/lib/esm/delimArray.js +10 -6
- package/lib/esm/delimArray.js.map +1 -1
- package/lib/esm/errorDoc.js +23 -51
- package/lib/esm/errorDoc.js.map +1 -1
- package/lib/esm/extensionSession.js +11 -16
- package/lib/esm/extensionSession.js.map +1 -1
- package/lib/esm/extensionTransport.js +13 -19
- package/lib/esm/extensionTransport.js.map +1 -1
- package/lib/esm/index.js +236 -21
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/lookerSDKError.js +13 -12
- package/lib/esm/lookerSDKError.js.map +1 -1
- package/lib/esm/oauthSession.js +23 -66
- package/lib/esm/oauthSession.js.map +1 -1
- package/lib/esm/paging.js +24 -71
- package/lib/esm/paging.js.map +1 -1
- package/lib/esm/platformServices.js.map +1 -1
- package/lib/esm/proxySession.js +13 -13
- package/lib/esm/proxySession.js.map +1 -1
- package/lib/esm/testUtils/index.js +17 -0
- package/lib/esm/testUtils/index.js.map +1 -0
- package/lib/esm/testUtils/testUtils.js +46 -0
- package/lib/esm/testUtils/testUtils.js.map +1 -0
- package/lib/esm/transport.js +57 -62
- package/lib/esm/transport.js.map +1 -1
- package/lib/extensionSession.js +3 -17
- package/lib/extensionSession.js.map +1 -1
- package/lib/extensionTransport.js +5 -20
- package/lib/extensionTransport.js.map +1 -1
- package/lib/index.js +0 -42
- package/lib/index.js.map +1 -1
- package/lib/lookerSDKError.js +5 -13
- package/lib/lookerSDKError.js.map +1 -1
- package/lib/oauthSession.js +8 -63
- package/lib/oauthSession.js.map +1 -1
- package/lib/paging.js +5 -70
- package/lib/paging.js.map +1 -1
- package/lib/platformServices.js +1 -1
- package/lib/platformServices.js.map +1 -1
- package/lib/proxySession.js +0 -12
- package/lib/proxySession.js.map +1 -1
- package/lib/testUtils/index.js +0 -2
- package/lib/testUtils/index.js.map +1 -1
- package/lib/testUtils/testUtils.js +1 -16
- package/lib/testUtils/testUtils.js.map +1 -1
- package/lib/transport.js +8 -50
- package/lib/transport.js.map +1 -1
- package/package.json +3 -3
package/lib/paging.js
CHANGED
|
@@ -3,23 +3,19 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.linkHeaderParser = exports.TotalCountHeader = exports.Paging = exports.LinkHeader = void 0;
|
|
7
7
|
exports.pageAll = pageAll;
|
|
8
|
-
exports.
|
|
9
|
-
|
|
8
|
+
exports.pager = pager;
|
|
10
9
|
var _transport = require("./transport");
|
|
11
|
-
|
|
12
|
-
function
|
|
13
|
-
|
|
10
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
11
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
12
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
14
13
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
15
|
-
|
|
16
14
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
17
|
-
|
|
18
15
|
var LinkHeader = 'Link';
|
|
19
16
|
exports.LinkHeader = LinkHeader;
|
|
20
17
|
var TotalCountHeader = 'X-Total-Count';
|
|
21
18
|
exports.TotalCountHeader = TotalCountHeader;
|
|
22
|
-
|
|
23
19
|
var linkHeaderParser = linkHeader => {
|
|
24
20
|
var re = /<\s*(.*)\s*>;\s*rel="\s*(.*)\s*"\s*/gm;
|
|
25
21
|
var links = linkHeader.split(',');
|
|
@@ -27,7 +23,6 @@ var linkHeaderParser = linkHeader => {
|
|
|
27
23
|
var arrRes;
|
|
28
24
|
links.forEach(link => {
|
|
29
25
|
link = link.trim();
|
|
30
|
-
|
|
31
26
|
while (arrRes = re.exec(link)) {
|
|
32
27
|
var key = arrRes[2].split(' ')[0].trim().toLocaleLowerCase();
|
|
33
28
|
obj[key] = {
|
|
@@ -39,31 +34,25 @@ var linkHeaderParser = linkHeader => {
|
|
|
39
34
|
});
|
|
40
35
|
return obj;
|
|
41
36
|
};
|
|
42
|
-
|
|
43
37
|
exports.linkHeaderParser = linkHeaderParser;
|
|
44
|
-
|
|
45
38
|
function pager(_x, _x2, _x3) {
|
|
46
39
|
return _pager.apply(this, arguments);
|
|
47
40
|
}
|
|
48
|
-
|
|
49
41
|
function _pager() {
|
|
50
42
|
_pager = _asyncToGenerator(function* (sdk, pageFunc, options) {
|
|
51
43
|
return yield new Paging(sdk, pageFunc, options).init();
|
|
52
44
|
});
|
|
53
45
|
return _pager.apply(this, arguments);
|
|
54
46
|
}
|
|
55
|
-
|
|
56
47
|
function pageAll(_x4, _x5) {
|
|
57
48
|
return _pageAll.apply(this, arguments);
|
|
58
49
|
}
|
|
59
|
-
|
|
60
50
|
function _pageAll() {
|
|
61
51
|
_pageAll = _asyncToGenerator(function* (sdk, pageFunc) {
|
|
62
52
|
var onPage = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : page => page;
|
|
63
53
|
var options = arguments.length > 3 ? arguments[3] : undefined;
|
|
64
54
|
var paged = yield pager(sdk, pageFunc, options);
|
|
65
55
|
onPage(paged.items);
|
|
66
|
-
|
|
67
56
|
try {
|
|
68
57
|
while (paged.more()) {
|
|
69
58
|
onPage(yield sdk.ok(paged.nextPage()));
|
|
@@ -71,112 +60,83 @@ function _pageAll() {
|
|
|
71
60
|
} catch (err) {
|
|
72
61
|
return Promise.reject(err);
|
|
73
62
|
}
|
|
74
|
-
|
|
75
63
|
return paged;
|
|
76
64
|
});
|
|
77
65
|
return _pageAll.apply(this, arguments);
|
|
78
66
|
}
|
|
79
|
-
|
|
80
67
|
class Paging {
|
|
81
68
|
constructor(sdk, func, options) {
|
|
82
69
|
this.sdk = sdk;
|
|
83
70
|
this.func = func;
|
|
84
71
|
this.options = options;
|
|
85
|
-
|
|
86
72
|
_defineProperty(this, "items", []);
|
|
87
|
-
|
|
88
73
|
_defineProperty(this, "links", {});
|
|
89
|
-
|
|
90
74
|
_defineProperty(this, "total", -1);
|
|
91
|
-
|
|
92
75
|
_defineProperty(this, "offset", -1);
|
|
93
|
-
|
|
94
76
|
_defineProperty(this, "limit", -1);
|
|
95
|
-
|
|
96
77
|
_defineProperty(this, "transport", void 0);
|
|
97
|
-
|
|
98
78
|
this.transport = sdk.authSession.transport;
|
|
99
79
|
}
|
|
100
|
-
|
|
101
80
|
rawCatch(func) {
|
|
102
81
|
var _this = this;
|
|
103
|
-
|
|
104
82
|
return _asyncToGenerator(function* () {
|
|
105
83
|
var raw = {};
|
|
106
84
|
var saved = _this.transport.observer;
|
|
107
|
-
|
|
108
85
|
try {
|
|
109
86
|
_this.transport.observer = response => {
|
|
110
87
|
if (saved) {
|
|
111
88
|
response = saved(response);
|
|
112
89
|
}
|
|
113
|
-
|
|
114
90
|
raw = response;
|
|
115
91
|
return response;
|
|
116
92
|
};
|
|
117
|
-
|
|
118
93
|
_this.items = yield (0, _transport.sdkOk)(func());
|
|
119
94
|
} finally {
|
|
120
95
|
_this.transport.observer = saved;
|
|
121
96
|
}
|
|
122
|
-
|
|
123
97
|
if (Object.keys(raw).length === 0 || Object.keys(raw.headers).length === 0) return Promise.reject(new Error('No paging headers were found'));
|
|
124
|
-
|
|
125
98
|
_this.parse(raw);
|
|
126
|
-
|
|
127
99
|
return _this;
|
|
128
100
|
})();
|
|
129
101
|
}
|
|
130
|
-
|
|
131
102
|
get page() {
|
|
132
103
|
if (this.limit < 1 || this.offset < 0) return -1;
|
|
133
104
|
var x = this.offset / this.limit + 1;
|
|
134
105
|
return Math.ceil(x);
|
|
135
106
|
}
|
|
136
|
-
|
|
137
107
|
get pages() {
|
|
138
108
|
if (this.total < 1 || this.limit < 1) return -1;
|
|
139
109
|
var x = this.total / this.limit;
|
|
140
110
|
return Math.ceil(x);
|
|
141
111
|
}
|
|
142
|
-
|
|
143
112
|
init() {
|
|
144
113
|
var _this2 = this;
|
|
145
|
-
|
|
146
114
|
return _asyncToGenerator(function* () {
|
|
147
115
|
return yield _this2.rawCatch(_this2.func);
|
|
148
116
|
})();
|
|
149
117
|
}
|
|
150
|
-
|
|
151
118
|
hasRel(link) {
|
|
152
119
|
return !!this.links[link];
|
|
153
120
|
}
|
|
154
|
-
|
|
155
121
|
more() {
|
|
156
122
|
return this.hasRel('next');
|
|
157
123
|
}
|
|
158
|
-
|
|
159
124
|
static paramDefault(value, defaultValue) {
|
|
160
125
|
var convert = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : v => parseInt(v, 10);
|
|
161
126
|
if (value === null) return defaultValue;
|
|
162
127
|
return convert(value);
|
|
163
128
|
}
|
|
164
|
-
|
|
165
129
|
reset() {
|
|
166
130
|
this.links = {};
|
|
167
131
|
this.total = this.offset = this.limit = -1;
|
|
168
132
|
this.items = [];
|
|
169
133
|
}
|
|
170
|
-
|
|
171
134
|
getRel(name, limit, offset) {
|
|
172
135
|
var _this3 = this;
|
|
173
|
-
|
|
174
136
|
return _asyncToGenerator(function* () {
|
|
175
137
|
var rel = _this3.links[name];
|
|
176
138
|
var result;
|
|
177
|
-
|
|
178
139
|
_this3.reset();
|
|
179
|
-
|
|
180
140
|
if (!rel) {
|
|
181
141
|
result = {
|
|
182
142
|
ok: true,
|
|
@@ -184,18 +144,14 @@ class Paging {
|
|
|
184
144
|
};
|
|
185
145
|
return result;
|
|
186
146
|
}
|
|
187
|
-
|
|
188
147
|
var authenticator = init => {
|
|
189
148
|
return _this3.sdk.authSession.authenticate(init);
|
|
190
149
|
};
|
|
191
|
-
|
|
192
150
|
var link = rel.url;
|
|
193
|
-
|
|
194
151
|
if (limit !== undefined) {
|
|
195
152
|
if (offset === undefined) {
|
|
196
153
|
offset = 0;
|
|
197
154
|
}
|
|
198
|
-
|
|
199
155
|
if (limit < 1 || offset < 0) {
|
|
200
156
|
result = {
|
|
201
157
|
ok: false,
|
|
@@ -203,19 +159,15 @@ class Paging {
|
|
|
203
159
|
};
|
|
204
160
|
return result;
|
|
205
161
|
}
|
|
206
|
-
|
|
207
162
|
var url = new URL(link);
|
|
208
163
|
var params = url.searchParams;
|
|
209
164
|
params.set('limit', limit.toString());
|
|
210
165
|
params.set('offset', offset.toString());
|
|
211
166
|
link = url.toString();
|
|
212
167
|
}
|
|
213
|
-
|
|
214
168
|
var raw = yield _this3.transport.rawRequest('GET', link, undefined, undefined, authenticator, _this3.options);
|
|
215
|
-
|
|
216
169
|
try {
|
|
217
170
|
_this3.parse(raw);
|
|
218
|
-
|
|
219
171
|
_this3.items = yield (0, _transport.sdkOk)(_this3.transport.parseResponse(raw));
|
|
220
172
|
result = {
|
|
221
173
|
ok: true,
|
|
@@ -227,71 +179,54 @@ class Paging {
|
|
|
227
179
|
error: e
|
|
228
180
|
};
|
|
229
181
|
}
|
|
230
|
-
|
|
231
182
|
return result;
|
|
232
183
|
})();
|
|
233
184
|
}
|
|
234
|
-
|
|
235
185
|
static findHeader(raw, name) {
|
|
236
186
|
return raw.headers[name] || raw.headers[name.toLowerCase()] || raw.headers[name.toUpperCase()];
|
|
237
187
|
}
|
|
238
|
-
|
|
239
188
|
parse(raw) {
|
|
240
189
|
var params = new URL(raw.url, 'http://default').searchParams;
|
|
241
190
|
this.limit = Paging.paramDefault(params.get('limit'), -1);
|
|
242
191
|
this.offset = Paging.paramDefault(params.get('offset'), this.limit > 0 ? 0 : -1);
|
|
243
192
|
var linkHeader = Paging.findHeader(raw, LinkHeader);
|
|
244
|
-
|
|
245
193
|
if (linkHeader) {
|
|
246
194
|
this.links = linkHeaderParser(linkHeader);
|
|
247
195
|
} else {
|
|
248
196
|
this.links = {};
|
|
249
197
|
}
|
|
250
|
-
|
|
251
198
|
var totalHeader = Paging.findHeader(raw, TotalCountHeader);
|
|
252
|
-
|
|
253
199
|
if (totalHeader) {
|
|
254
200
|
this.total = parseInt(totalHeader.trim(), 10);
|
|
255
201
|
} else {
|
|
256
202
|
this.total = -1;
|
|
257
203
|
}
|
|
258
|
-
|
|
259
204
|
return this;
|
|
260
205
|
}
|
|
261
|
-
|
|
262
206
|
firstPage() {
|
|
263
207
|
var _this4 = this;
|
|
264
|
-
|
|
265
208
|
return _asyncToGenerator(function* () {
|
|
266
209
|
return yield _this4.getRel('first');
|
|
267
210
|
})();
|
|
268
211
|
}
|
|
269
|
-
|
|
270
212
|
lastPage() {
|
|
271
213
|
var _this5 = this;
|
|
272
|
-
|
|
273
214
|
return _asyncToGenerator(function* () {
|
|
274
215
|
return yield _this5.getRel('last');
|
|
275
216
|
})();
|
|
276
217
|
}
|
|
277
|
-
|
|
278
218
|
nextPage() {
|
|
279
219
|
var _this6 = this;
|
|
280
|
-
|
|
281
220
|
return _asyncToGenerator(function* () {
|
|
282
221
|
return yield _this6.getRel('next');
|
|
283
222
|
})();
|
|
284
223
|
}
|
|
285
|
-
|
|
286
224
|
prevPage() {
|
|
287
225
|
var _this7 = this;
|
|
288
|
-
|
|
289
226
|
return _asyncToGenerator(function* () {
|
|
290
227
|
return yield _this7.getRel('prev');
|
|
291
228
|
})();
|
|
292
229
|
}
|
|
293
|
-
|
|
294
230
|
}
|
|
295
|
-
|
|
296
231
|
exports.Paging = Paging;
|
|
297
232
|
//# sourceMappingURL=paging.js.map
|
package/lib/paging.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/paging.ts"],"names":["LinkHeader","TotalCountHeader","linkHeaderParser","linkHeader","re","links","split","obj","arrRes","forEach","link","trim","exec","key","toLocaleLowerCase","url","rel","name","pager","sdk","pageFunc","options","Paging","init","pageAll","onPage","page","paged","items","more","ok","nextPage","err","Promise","reject","constructor","func","transport","authSession","rawCatch","raw","saved","observer","response","Object","keys","length","headers","Error","parse","limit","offset","x","Math","ceil","pages","total","hasRel","paramDefault","value","defaultValue","convert","v","parseInt","reset","getRel","result","authenticator","authenticate","undefined","error","URL","params","searchParams","set","toString","rawRequest","parseResponse","e","findHeader","toLowerCase","toUpperCase","get","totalHeader","firstPage","lastPage","prevPage"],"mappings":"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","sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nimport type { IRawResponse, ITransportSettings, SDKResponse } from './transport'\nimport { sdkOk } from './transport'\nimport type { IAPIMethods } from './apiMethods'\nimport type { BaseTransport } from './baseTransport'\n\nexport const LinkHeader = 'Link'\nexport const TotalCountHeader = 'X-Total-Count'\n\n/**\n * Types of paging link relative URLs\n * based on https://docs.github.com/en/rest/overview/resources-in-the-rest-api#link-header\n */\nexport type PageLinkRel = 'first' | 'last' | 'next' | 'prev'\n\n/** Constraints for TSuccess type */\ninterface ILength {\n length: number\n}\n\n/** Result paging function call */\nexport type PagingFunc<TSuccess, TError> = () => Promise<\n SDKResponse<TSuccess, TError>\n>\n\n/** Page link structure */\nexport interface IPageLink {\n /** Name of link */\n name?: string\n /** Type of link */\n rel: PageLinkRel\n /** Media type for link */\n mediaType?: string\n /** URL for retrieving the link results */\n url: string\n}\n\n/**\n * Collection of page links\n *\n * TODO can this be Record<PageLinkRel, IPageLink> instead and still init to {}?\n */\nexport type PageLinks = Record<string, IPageLink>\n\nexport interface IPager<TSuccess, TError> {\n /** Total number of available items being paginated */\n total: number\n /** Offset extracted from pager request */\n offset: number\n /** Limit extracted from pager request */\n limit: number\n /** Paging links extracted from Link header */\n links: PageLinks\n /** Latest items returned from response */\n items: TSuccess\n /** Captured from the original paging request */\n options?: Partial<ITransportSettings>\n /** Total number of pages. -1 if not known. */\n pages: number\n /** Current page. -1 if not known. */\n page: number\n\n /**\n * Is the specified link rel defined in the Link header?\n * @param link to check\n */\n hasRel(link: PageLinkRel): boolean\n\n /**\n * GET the requested relative link\n *\n * if the requested link is not defined, all calculated values are reset to their defaults, including\n * `total`, `items`, `offset`, and `limit`\n *\n * @param name of Link Relationship\n * @param limit optional limit override to replace limit saved in `rel`\n * @param offset optional offset override to replace offset saved in `rel`\n */\n getRel(\n name: PageLinkRel,\n limit?: number,\n offset?: number\n ): Promise<SDKResponse<TSuccess, TError>>\n\n /** Get the first page of items. This is the same as offset=0 */\n firstPage(): Promise<SDKResponse<TSuccess, TError>>\n /**\n * Get the last page of items\n *\n * @remarks This link is only provided if `total` is known.\n */\n lastPage(): Promise<SDKResponse<TSuccess, TError>>\n /**\n * Get the next page of items\n *\n * @remarks This link is provided if `total` is known, or if the number of items returned == `limit`. In the latter case, this function may return an empty result set.\n */\n nextPage(): Promise<SDKResponse<TSuccess, TError>>\n /**\n * Get the previous page of items\n *\n * @remarks This link is provided if the last page was not the first page.\n */\n prevPage(): Promise<SDKResponse<TSuccess, TError>>\n\n /** `true` if the `next` link is defined */\n more(): boolean\n}\n\n/**\n * Parse a link header to extract rels\n * @param linkHeader to parse\n *\n * Several different approaches are discussed at https://stackoverflow.com/questions/8735792/how-to-parse-link-header-from-github-api\n *\n * Unfortunately, none of them are a good implementation\n *\n */\nexport const linkHeaderParser = (linkHeader: string): PageLinks => {\n const re = /<\\s*(.*)\\s*>;\\s*rel=\"\\s*(.*)\\s*\"\\s*/gm\n const links = linkHeader.split(',')\n const obj: PageLinks = {}\n let arrRes\n\n links.forEach((link) => {\n link = link.trim()\n while ((arrRes = re.exec(link))) {\n const key = arrRes[2].split(' ')[0].trim().toLocaleLowerCase()\n obj[key] = {\n url: arrRes[1].trim(),\n rel: key as PageLinkRel,\n name: arrRes[2].trim(),\n }\n }\n })\n return obj\n}\n\n/** Event to observe the paging call */\nexport type PageObserver<TSuccess> = (\n /** Current retrieved page of results */\n page: TSuccess\n) => TSuccess\n\n/**\n * Create an API response pager for an endpoint that returns a Link header\n * @param sdk implementation of IAPIMethods. Can be a full SDK or functional auth session. The active transport object is captured from this parameter, which is why it must be passed separately from the paging function.\n * @param pageFunc sdk call that includes a paging header\n * @param options transport options override to capture and use in paging requests\n *\n * @remarks `TSuccess` must be a collection type that supports `length`\n */\nexport async function pager<TSuccess extends ILength, TError>(\n sdk: IAPIMethods,\n pageFunc: PagingFunc<TSuccess, TError>,\n options?: Partial<ITransportSettings>\n): Promise<IPager<TSuccess, TError>> {\n return await new Paging<TSuccess, TError>(sdk, pageFunc, options).init()\n}\n\n/**\n * Create an API response pager and iterate through all pages, calling a page event per page\n * @param sdk implementation of IAPIMethods. Can be a full SDK or functional auth session. The active transport object is captured from this parameter, which is why it must be passed separately from the paging function.\n * @param pageFunc sdk call that includes a paging header\n * @param onPage observer of the latest page of results. Defaults to noop.\n * @param options transport options override to capture and use in paging requests\n *\n * @remarks `TSuccess` must be a collection type that supports `length`\n */\nexport async function pageAll<TSuccess extends ILength, TError>(\n sdk: IAPIMethods,\n pageFunc: PagingFunc<TSuccess, TError>,\n onPage: PageObserver<TSuccess> = (page: TSuccess) => page,\n options?: Partial<ITransportSettings>\n): Promise<IPager<TSuccess, TError>> {\n const paged = await pager(sdk, pageFunc, options)\n // Process the first page\n onPage(paged.items)\n try {\n while (paged.more()) {\n // Pass the page items to the event\n onPage(await sdk.ok(paged.nextPage()))\n }\n } catch (err) {\n return Promise.reject(err)\n }\n return paged\n}\n\n/**\n * Link header pages class\n */\nexport class Paging<TSuccess extends ILength, TError>\n implements IPager<TSuccess, TError>\n{\n items: TSuccess = [] as unknown as TSuccess\n links: PageLinks = {}\n total = -1\n offset = -1\n limit = -1\n\n private transport: BaseTransport\n\n /**\n * Create an API paginator\n * @param sdk functional AuthSession or full SDK implementation\n * @param func sdk function to call\n * @param options transport overrides to use for subsequent requests\n */\n constructor(\n public sdk: IAPIMethods,\n public func: PagingFunc<TSuccess, TError>,\n public options?: Partial<ITransportSettings>\n ) {\n this.transport = sdk.authSession.transport as BaseTransport\n }\n\n private async rawCatch(func: () => any) {\n let raw: IRawResponse = {} as IRawResponse\n const saved = this.transport.observer\n try {\n // Capture the raw request for header parsing\n this.transport.observer = (response: IRawResponse) => {\n if (saved) {\n // Chain the observer\n response = saved(response)\n }\n raw = response\n return response\n }\n this.items = await sdkOk(func())\n } finally {\n // Restore the previous observer (if any)\n this.transport.observer = saved\n }\n if (Object.keys(raw).length === 0 || Object.keys(raw.headers).length === 0)\n return Promise.reject(new Error('No paging headers were found'))\n this.parse(raw)\n return this\n }\n\n get page(): number {\n if (this.limit < 1 || this.offset < 0) return -1\n const x = this.offset / this.limit + 1\n return Math.ceil(x)\n }\n\n get pages(): number {\n if (this.total < 1 || this.limit < 1) return -1\n const x = this.total / this.limit\n return Math.ceil(x)\n }\n\n async init() {\n return await this.rawCatch(this.func)\n }\n\n hasRel(link: PageLinkRel): boolean {\n return !!this.links[link]\n }\n\n more() {\n return this.hasRel('next')\n }\n\n /**\n * Default string value\n * @param value to retrieve or default\n * @param defaultValue to apply if string is null\n * @param convert function to convert assigned string value\n * @private\n */\n private static paramDefault(\n value: string | null,\n defaultValue: any,\n convert = (v: string) => parseInt(v, 10)\n ) {\n if (value === null) return defaultValue\n return convert(value)\n }\n\n reset() {\n this.links = {}\n this.total = this.offset = this.limit = -1\n this.items = [] as unknown as TSuccess\n }\n\n async getRel(\n name: PageLinkRel,\n limit?: number,\n offset?: number\n ): Promise<SDKResponse<TSuccess, TError>> {\n const rel = this.links[name]\n let result: SDKResponse<TSuccess, TError>\n this.reset()\n if (!rel) {\n result = { ok: true, value: this.items }\n return result\n }\n const authenticator = (init: any) => {\n return this.sdk.authSession.authenticate(init)\n }\n\n let link = rel.url\n if (limit !== undefined) {\n if (offset === undefined) {\n offset = 0\n }\n if (limit < 1 || offset < 0) {\n result = {\n ok: false,\n error: new Error(\n 'limit must be > 0 and offset must be >= 0'\n ) as unknown as TError,\n }\n return result\n }\n const url = new URL(link)\n const params = url.searchParams\n params.set('limit', limit.toString())\n params.set('offset', offset.toString())\n link = url.toString()\n }\n const raw = await this.transport.rawRequest(\n 'GET',\n link,\n undefined,\n undefined,\n authenticator,\n this.options\n )\n try {\n this.parse(raw)\n this.items = await sdkOk(this.transport.parseResponse(raw))\n result = { ok: true, value: this.items }\n } catch (e: any) {\n result = { ok: false, error: e }\n }\n return result\n }\n\n static findHeader(raw: IRawResponse, name: string) {\n return (\n raw.headers[name] ||\n raw.headers[name.toLowerCase()] ||\n raw.headers[name.toUpperCase()]\n )\n }\n\n parse(raw: IRawResponse): IPager<TSuccess, TError> {\n const params = new URL(raw.url, 'http://default').searchParams\n this.limit = Paging.paramDefault(params.get('limit'), -1)\n this.offset = Paging.paramDefault(\n params.get('offset'),\n this.limit > 0 ? 0 : -1\n )\n const linkHeader = Paging.findHeader(raw, LinkHeader)\n if (linkHeader) {\n this.links = linkHeaderParser(linkHeader)\n } else {\n this.links = {}\n }\n const totalHeader = Paging.findHeader(raw, TotalCountHeader)\n if (totalHeader) {\n this.total = parseInt(totalHeader.trim(), 10)\n } else {\n this.total = -1\n }\n return this as unknown as IPager<TSuccess, TError>\n }\n\n async firstPage(): Promise<SDKResponse<TSuccess, TError>> {\n return await this.getRel('first')\n }\n\n async lastPage(): Promise<SDKResponse<TSuccess, TError>> {\n return await this.getRel('last')\n }\n\n async nextPage(): Promise<SDKResponse<TSuccess, TError>> {\n return await this.getRel('next')\n }\n\n async prevPage(): Promise<SDKResponse<TSuccess, TError>> {\n return await this.getRel('prev')\n }\n}\n"],"file":"paging.js"}
|
|
1
|
+
{"version":3,"file":"paging.js","names":["LinkHeader","TotalCountHeader","linkHeaderParser","linkHeader","re","links","split","obj","arrRes","forEach","link","trim","exec","key","toLocaleLowerCase","url","rel","name","pager","sdk","pageFunc","options","Paging","init","pageAll","onPage","page","paged","items","more","ok","nextPage","err","Promise","reject","constructor","func","transport","authSession","rawCatch","raw","saved","observer","response","sdkOk","Object","keys","length","headers","Error","parse","limit","offset","x","Math","ceil","pages","total","hasRel","paramDefault","value","defaultValue","convert","v","parseInt","reset","getRel","result","authenticator","authenticate","undefined","error","URL","params","searchParams","set","toString","rawRequest","parseResponse","e","findHeader","toLowerCase","toUpperCase","get","totalHeader","firstPage","lastPage","prevPage"],"sources":["../src/paging.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nimport type { IRawResponse, ITransportSettings, SDKResponse } from './transport'\nimport { sdkOk } from './transport'\nimport type { IAPIMethods } from './apiMethods'\nimport type { BaseTransport } from './baseTransport'\n\nexport const LinkHeader = 'Link'\nexport const TotalCountHeader = 'X-Total-Count'\n\n/**\n * Types of paging link relative URLs\n * based on https://docs.github.com/en/rest/overview/resources-in-the-rest-api#link-header\n */\nexport type PageLinkRel = 'first' | 'last' | 'next' | 'prev'\n\n/** Constraints for TSuccess type */\ninterface ILength {\n length: number\n}\n\n/** Result paging function call */\nexport type PagingFunc<TSuccess, TError> = () => Promise<\n SDKResponse<TSuccess, TError>\n>\n\n/** Page link structure */\nexport interface IPageLink {\n /** Name of link */\n name?: string\n /** Type of link */\n rel: PageLinkRel\n /** Media type for link */\n mediaType?: string\n /** URL for retrieving the link results */\n url: string\n}\n\n/**\n * Collection of page links\n *\n * TODO can this be Record<PageLinkRel, IPageLink> instead and still init to {}?\n */\nexport type PageLinks = Record<string, IPageLink>\n\nexport interface IPager<TSuccess, TError> {\n /** Total number of available items being paginated */\n total: number\n /** Offset extracted from pager request */\n offset: number\n /** Limit extracted from pager request */\n limit: number\n /** Paging links extracted from Link header */\n links: PageLinks\n /** Latest items returned from response */\n items: TSuccess\n /** Captured from the original paging request */\n options?: Partial<ITransportSettings>\n /** Total number of pages. -1 if not known. */\n pages: number\n /** Current page. -1 if not known. */\n page: number\n\n /**\n * Is the specified link rel defined in the Link header?\n * @param link to check\n */\n hasRel(link: PageLinkRel): boolean\n\n /**\n * GET the requested relative link\n *\n * if the requested link is not defined, all calculated values are reset to their defaults, including\n * `total`, `items`, `offset`, and `limit`\n *\n * @param name of Link Relationship\n * @param limit optional limit override to replace limit saved in `rel`\n * @param offset optional offset override to replace offset saved in `rel`\n */\n getRel(\n name: PageLinkRel,\n limit?: number,\n offset?: number\n ): Promise<SDKResponse<TSuccess, TError>>\n\n /** Get the first page of items. This is the same as offset=0 */\n firstPage(): Promise<SDKResponse<TSuccess, TError>>\n /**\n * Get the last page of items\n *\n * @remarks This link is only provided if `total` is known.\n */\n lastPage(): Promise<SDKResponse<TSuccess, TError>>\n /**\n * Get the next page of items\n *\n * @remarks This link is provided if `total` is known, or if the number of items returned == `limit`. In the latter case, this function may return an empty result set.\n */\n nextPage(): Promise<SDKResponse<TSuccess, TError>>\n /**\n * Get the previous page of items\n *\n * @remarks This link is provided if the last page was not the first page.\n */\n prevPage(): Promise<SDKResponse<TSuccess, TError>>\n\n /** `true` if the `next` link is defined */\n more(): boolean\n}\n\n/**\n * Parse a link header to extract rels\n * @param linkHeader to parse\n *\n * Several different approaches are discussed at https://stackoverflow.com/questions/8735792/how-to-parse-link-header-from-github-api\n *\n * Unfortunately, none of them are a good implementation\n *\n */\nexport const linkHeaderParser = (linkHeader: string): PageLinks => {\n const re = /<\\s*(.*)\\s*>;\\s*rel=\"\\s*(.*)\\s*\"\\s*/gm\n const links = linkHeader.split(',')\n const obj: PageLinks = {}\n let arrRes\n\n links.forEach((link) => {\n link = link.trim()\n while ((arrRes = re.exec(link))) {\n const key = arrRes[2].split(' ')[0].trim().toLocaleLowerCase()\n obj[key] = {\n url: arrRes[1].trim(),\n rel: key as PageLinkRel,\n name: arrRes[2].trim(),\n }\n }\n })\n return obj\n}\n\n/** Event to observe the paging call */\nexport type PageObserver<TSuccess> = (\n /** Current retrieved page of results */\n page: TSuccess\n) => TSuccess\n\n/**\n * Create an API response pager for an endpoint that returns a Link header\n * @param sdk implementation of IAPIMethods. Can be a full SDK or functional auth session. The active transport object is captured from this parameter, which is why it must be passed separately from the paging function.\n * @param pageFunc sdk call that includes a paging header\n * @param options transport options override to capture and use in paging requests\n *\n * @remarks `TSuccess` must be a collection type that supports `length`\n */\nexport async function pager<TSuccess extends ILength, TError>(\n sdk: IAPIMethods,\n pageFunc: PagingFunc<TSuccess, TError>,\n options?: Partial<ITransportSettings>\n): Promise<IPager<TSuccess, TError>> {\n return await new Paging<TSuccess, TError>(sdk, pageFunc, options).init()\n}\n\n/**\n * Create an API response pager and iterate through all pages, calling a page event per page\n * @param sdk implementation of IAPIMethods. Can be a full SDK or functional auth session. The active transport object is captured from this parameter, which is why it must be passed separately from the paging function.\n * @param pageFunc sdk call that includes a paging header\n * @param onPage observer of the latest page of results. Defaults to noop.\n * @param options transport options override to capture and use in paging requests\n *\n * @remarks `TSuccess` must be a collection type that supports `length`\n */\nexport async function pageAll<TSuccess extends ILength, TError>(\n sdk: IAPIMethods,\n pageFunc: PagingFunc<TSuccess, TError>,\n onPage: PageObserver<TSuccess> = (page: TSuccess) => page,\n options?: Partial<ITransportSettings>\n): Promise<IPager<TSuccess, TError>> {\n const paged = await pager(sdk, pageFunc, options)\n // Process the first page\n onPage(paged.items)\n try {\n while (paged.more()) {\n // Pass the page items to the event\n onPage(await sdk.ok(paged.nextPage()))\n }\n } catch (err) {\n return Promise.reject(err)\n }\n return paged\n}\n\n/**\n * Link header pages class\n */\nexport class Paging<TSuccess extends ILength, TError>\n implements IPager<TSuccess, TError>\n{\n items: TSuccess = [] as unknown as TSuccess\n links: PageLinks = {}\n total = -1\n offset = -1\n limit = -1\n\n private transport: BaseTransport\n\n /**\n * Create an API paginator\n * @param sdk functional AuthSession or full SDK implementation\n * @param func sdk function to call\n * @param options transport overrides to use for subsequent requests\n */\n constructor(\n public sdk: IAPIMethods,\n public func: PagingFunc<TSuccess, TError>,\n public options?: Partial<ITransportSettings>\n ) {\n this.transport = sdk.authSession.transport as BaseTransport\n }\n\n private async rawCatch(func: () => any) {\n let raw: IRawResponse = {} as IRawResponse\n const saved = this.transport.observer\n try {\n // Capture the raw request for header parsing\n this.transport.observer = (response: IRawResponse) => {\n if (saved) {\n // Chain the observer\n response = saved(response)\n }\n raw = response\n return response\n }\n this.items = await sdkOk(func())\n } finally {\n // Restore the previous observer (if any)\n this.transport.observer = saved\n }\n if (Object.keys(raw).length === 0 || Object.keys(raw.headers).length === 0)\n return Promise.reject(new Error('No paging headers were found'))\n this.parse(raw)\n return this\n }\n\n get page(): number {\n if (this.limit < 1 || this.offset < 0) return -1\n const x = this.offset / this.limit + 1\n return Math.ceil(x)\n }\n\n get pages(): number {\n if (this.total < 1 || this.limit < 1) return -1\n const x = this.total / this.limit\n return Math.ceil(x)\n }\n\n async init() {\n return await this.rawCatch(this.func)\n }\n\n hasRel(link: PageLinkRel): boolean {\n return !!this.links[link]\n }\n\n more() {\n return this.hasRel('next')\n }\n\n /**\n * Default string value\n * @param value to retrieve or default\n * @param defaultValue to apply if string is null\n * @param convert function to convert assigned string value\n * @private\n */\n private static paramDefault(\n value: string | null,\n defaultValue: any,\n convert = (v: string) => parseInt(v, 10)\n ) {\n if (value === null) return defaultValue\n return convert(value)\n }\n\n reset() {\n this.links = {}\n this.total = this.offset = this.limit = -1\n this.items = [] as unknown as TSuccess\n }\n\n async getRel(\n name: PageLinkRel,\n limit?: number,\n offset?: number\n ): Promise<SDKResponse<TSuccess, TError>> {\n const rel = this.links[name]\n let result: SDKResponse<TSuccess, TError>\n this.reset()\n if (!rel) {\n result = { ok: true, value: this.items }\n return result\n }\n const authenticator = (init: any) => {\n return this.sdk.authSession.authenticate(init)\n }\n\n let link = rel.url\n if (limit !== undefined) {\n if (offset === undefined) {\n offset = 0\n }\n if (limit < 1 || offset < 0) {\n result = {\n ok: false,\n error: new Error(\n 'limit must be > 0 and offset must be >= 0'\n ) as unknown as TError,\n }\n return result\n }\n const url = new URL(link)\n const params = url.searchParams\n params.set('limit', limit.toString())\n params.set('offset', offset.toString())\n link = url.toString()\n }\n const raw = await this.transport.rawRequest(\n 'GET',\n link,\n undefined,\n undefined,\n authenticator,\n this.options\n )\n try {\n this.parse(raw)\n this.items = await sdkOk(this.transport.parseResponse(raw))\n result = { ok: true, value: this.items }\n } catch (e: any) {\n result = { ok: false, error: e }\n }\n return result\n }\n\n static findHeader(raw: IRawResponse, name: string) {\n return (\n raw.headers[name] ||\n raw.headers[name.toLowerCase()] ||\n raw.headers[name.toUpperCase()]\n )\n }\n\n parse(raw: IRawResponse): IPager<TSuccess, TError> {\n const params = new URL(raw.url, 'http://default').searchParams\n this.limit = Paging.paramDefault(params.get('limit'), -1)\n this.offset = Paging.paramDefault(\n params.get('offset'),\n this.limit > 0 ? 0 : -1\n )\n const linkHeader = Paging.findHeader(raw, LinkHeader)\n if (linkHeader) {\n this.links = linkHeaderParser(linkHeader)\n } else {\n this.links = {}\n }\n const totalHeader = Paging.findHeader(raw, TotalCountHeader)\n if (totalHeader) {\n this.total = parseInt(totalHeader.trim(), 10)\n } else {\n this.total = -1\n }\n return this as unknown as IPager<TSuccess, TError>\n }\n\n async firstPage(): Promise<SDKResponse<TSuccess, TError>> {\n return await this.getRel('first')\n }\n\n async lastPage(): Promise<SDKResponse<TSuccess, TError>> {\n return await this.getRel('last')\n }\n\n async nextPage(): Promise<SDKResponse<TSuccess, TError>> {\n return await this.getRel('next')\n }\n\n async prevPage(): Promise<SDKResponse<TSuccess, TError>> {\n return await this.getRel('prev')\n }\n}\n"],"mappings":"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"}
|
package/lib/platformServices.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
//# sourceMappingURL=platformServices.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"platformServices.js","names":[],"sources":["../src/platformServices.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nimport type { IApiSettings } from './apiSettings'\nimport type { ITransport } from './transport'\nimport type { ICryptoHash } from './cryptoHash'\n\n/**\n * Contract for OAuth authentication services\n */\nexport interface IPlatformServices {\n settings: IApiSettings\n transport: ITransport\n crypto: ICryptoHash\n}\n"],"mappings":""}
|
package/lib/proxySession.js
CHANGED
|
@@ -4,44 +4,32 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.ProxySession = void 0;
|
|
7
|
-
|
|
8
7
|
var _authSession = require("./authSession");
|
|
9
|
-
|
|
10
8
|
var _browserTransport = require("./browserTransport");
|
|
11
|
-
|
|
12
9
|
var _transport = require("./transport");
|
|
13
|
-
|
|
14
10
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
15
|
-
|
|
16
11
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
17
|
-
|
|
18
12
|
class ProxySession extends _authSession.AuthSession {
|
|
19
13
|
constructor(settings, proxyUrl, transport) {
|
|
20
14
|
super(settings, transport || new _browserTransport.BrowserTransport(settings));
|
|
21
15
|
this.settings = settings;
|
|
22
16
|
this.proxyUrl = proxyUrl;
|
|
23
17
|
}
|
|
24
|
-
|
|
25
18
|
isAuthenticated() {
|
|
26
19
|
return true;
|
|
27
20
|
}
|
|
28
|
-
|
|
29
21
|
authenticate(props) {
|
|
30
22
|
var _this = this;
|
|
31
|
-
|
|
32
23
|
return _asyncToGenerator(function* () {
|
|
33
24
|
if (!props.headers) {
|
|
34
25
|
props.headers = {};
|
|
35
26
|
}
|
|
36
|
-
|
|
37
27
|
props.headers['X-Forwarded-For'] = props.url;
|
|
38
28
|
props.headers[_transport.LookerAppId] = _transport.agentPrefix;
|
|
39
29
|
props.url = _this.proxyUrl;
|
|
40
30
|
return props;
|
|
41
31
|
})();
|
|
42
32
|
}
|
|
43
|
-
|
|
44
33
|
}
|
|
45
|
-
|
|
46
34
|
exports.ProxySession = ProxySession;
|
|
47
35
|
//# sourceMappingURL=proxySession.js.map
|
package/lib/proxySession.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"proxySession.js","names":["ProxySession","AuthSession","constructor","settings","proxyUrl","transport","BrowserTransport","isAuthenticated","authenticate","props","headers","url","LookerAppId","agentPrefix"],"sources":["../src/proxySession.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nimport { AuthSession } from './authSession'\nimport { BrowserTransport } from './browserTransport'\nimport type { ITransport, IRequestProps } from './transport'\nimport { LookerAppId, agentPrefix } from './transport'\nimport type { IApiSettings } from './apiSettings'\n\n/**\n * An AuthSession class intended for use with proxied requests\n *\n * This session uses `authenticate` to modify all requests to pass through a proxy server with\n * passing the request to the proxy server specified in the `proxyUrl` parameter, and sets\n * the original request path as an `X-Forwarded-For` header.\n *\n */\nexport abstract class ProxySession extends AuthSession {\n constructor(\n public settings: IApiSettings,\n public proxyUrl: string,\n transport?: ITransport\n ) {\n super(settings, transport || new BrowserTransport(settings))\n }\n\n /**\n * Proxy session is considered to be always authenticated since the proxy handles all auth\n *\n * @returns `true` since the proxy handles all authentication\n */\n isAuthenticated() {\n return true\n }\n\n /**\n * This implementation swaps the request's path with the proxy url, and puts the original\n * request path in the `X-Forwarded-For` header, presuming that the proxy server will add API authentication\n * information to the request that gets submitted to the Looker API, then forward the API response to the requestor\n *\n * @param props the properties of the request\n * @returns the same request properties with \"authentication\" data added\n *\n */\n async authenticate(props: IRequestProps) {\n if (!props.headers) {\n props.headers = {}\n }\n props.headers['X-Forwarded-For'] = props.url\n props.headers[LookerAppId] = agentPrefix\n props.url = this.proxyUrl\n return props\n }\n}\n"],"mappings":";;;;;;AA0BA;AACA;AAEA;AAAsD;AAAA;AAW/C,MAAeA,YAAY,SAASC,wBAAW,CAAC;EACrDC,WAAW,CACFC,QAAsB,EACtBC,QAAgB,EACvBC,SAAsB,EACtB;IACA,KAAK,CAACF,QAAQ,EAAEE,SAAS,IAAI,IAAIC,kCAAgB,CAACH,QAAQ,CAAC,CAAC;IAAA,KAJrDA,QAAsB,GAAtBA,QAAsB;IAAA,KACtBC,QAAgB,GAAhBA,QAAgB;EAIzB;EAOAG,eAAe,GAAG;IAChB,OAAO,IAAI;EACb;EAWMC,YAAY,CAACC,KAAoB,EAAE;IAAA;IAAA;MACvC,IAAI,CAACA,KAAK,CAACC,OAAO,EAAE;QAClBD,KAAK,CAACC,OAAO,GAAG,CAAC,CAAC;MACpB;MACAD,KAAK,CAACC,OAAO,CAAC,iBAAiB,CAAC,GAAGD,KAAK,CAACE,GAAG;MAC5CF,KAAK,CAACC,OAAO,CAACE,sBAAW,CAAC,GAAGC,sBAAW;MACxCJ,KAAK,CAACE,GAAG,GAAG,KAAI,CAACP,QAAQ;MACzB,OAAOK,KAAK;IAAA;EACd;AACF;AAAC"}
|
package/lib/testUtils/index.js
CHANGED
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
|
|
7
6
|
var _testUtils = require("./testUtils");
|
|
8
|
-
|
|
9
7
|
Object.keys(_testUtils).forEach(function (key) {
|
|
10
8
|
if (key === "default" || key === "__esModule") return;
|
|
11
9
|
if (key in exports && exports[key] === _testUtils[key]) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/testUtils/index.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nexport * from './testUtils'\n"],"mappings":";;;;;AA0BA;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA"}
|
|
@@ -3,38 +3,24 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
7
|
-
|
|
6
|
+
exports.rootFile = exports.readFile = exports.getRootPath = exports.TestConfig = void 0;
|
|
8
7
|
var fs = _interopRequireWildcard(require("fs"));
|
|
9
|
-
|
|
10
8
|
var _path = _interopRequireDefault(require("path"));
|
|
11
|
-
|
|
12
9
|
var _dotenv = require("dotenv");
|
|
13
|
-
|
|
14
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
-
|
|
16
11
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
17
|
-
|
|
18
12
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
19
|
-
|
|
20
13
|
var utf8 = 'utf-8';
|
|
21
14
|
var homeToRoost = '../../../../';
|
|
22
|
-
|
|
23
15
|
var getRootPath = () => _path.default.join(__dirname, homeToRoost);
|
|
24
|
-
|
|
25
16
|
exports.getRootPath = getRootPath;
|
|
26
|
-
|
|
27
17
|
var rootFile = function rootFile() {
|
|
28
18
|
var fileName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
29
19
|
return _path.default.join(getRootPath(), fileName);
|
|
30
20
|
};
|
|
31
|
-
|
|
32
21
|
exports.rootFile = rootFile;
|
|
33
|
-
|
|
34
22
|
var readFile = fileName => fs.readFileSync(fileName, utf8);
|
|
35
|
-
|
|
36
23
|
exports.readFile = readFile;
|
|
37
|
-
|
|
38
24
|
var TestConfig = function TestConfig() {
|
|
39
25
|
var rootPath = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
40
26
|
(0, _dotenv.config)();
|
|
@@ -56,6 +42,5 @@ var TestConfig = function TestConfig() {
|
|
|
56
42
|
testPath
|
|
57
43
|
};
|
|
58
44
|
};
|
|
59
|
-
|
|
60
45
|
exports.TestConfig = TestConfig;
|
|
61
46
|
//# sourceMappingURL=testUtils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"testUtils.js","names":["utf8","homeToRoost","getRootPath","path","join","__dirname","rootFile","fileName","readFile","fs","readFileSync","TestConfig","rootPath","config","testFile","localIni","process","env","LOOKERSDK_INI","testPath","dataFile","testData","JSON","parse","testIni","iniFile","existsSync"],"sources":["../../src/testUtils/testUtils.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nimport * as fs from 'fs'\nimport path from 'path'\nimport { config } from 'dotenv'\n\nconst utf8 = 'utf-8'\n\n/**\n * Properties used for various typescript-based tests\n */\nexport interface ITestConfig {\n rootPath: string\n testPath: string\n dataFile: string\n localIni: string\n testData: any\n testIni: string\n}\n\nconst homeToRoost = '../../../../'\n\nexport const getRootPath = () => path.join(__dirname, homeToRoost)\nexport const rootFile = (fileName = '') => path.join(getRootPath(), fileName)\nexport const readFile = (fileName: string) => fs.readFileSync(fileName, utf8)\n\n/**\n * Reads configuration information, returning various test values\n * @param {string} rootPath\n * @returns {{testConfig: {[p: string]: any}; localIni: string; baseUrl: any; testData: any; apiVersion: any; testIni: string; configContents: string; rootPath: string; testSection: any; timeout: number}}\n * @constructor\n */\nexport const TestConfig = (rootPath = ''): ITestConfig => {\n config()\n const testFile = 'data.yml.json'\n rootPath = rootPath || getRootPath()\n let localIni = process.env.LOOKERSDK_INI || rootFile('looker.ini')\n const testPath = rootFile('test/')\n const dataFile = `${testPath}${testFile}`\n const testData = JSON.parse(fs.readFileSync(dataFile, utf8))\n let testIni = `${rootPath}${testData.iniFile}`\n\n // If .ini files don't exist, don't try to read them downstream and expect environment variables to be set\n if (!fs.existsSync(localIni)) localIni = ''\n if (!fs.existsSync(testIni)) testIni = ''\n\n return {\n dataFile,\n localIni,\n rootPath,\n testData,\n testIni,\n testPath,\n }\n}\n"],"mappings":";;;;;;AA0BA;AACA;AACA;AAA+B;AAAA;AAAA;AAE/B,IAAMA,IAAI,GAAG,OAAO;AAcpB,IAAMC,WAAW,GAAG,cAAc;AAE3B,IAAMC,WAAW,GAAG,MAAMC,aAAI,CAACC,IAAI,CAACC,SAAS,EAAEJ,WAAW,CAAC;AAAA;AAC3D,IAAMK,QAAQ,GAAG,SAAXA,QAAQ;EAAA,IAAIC,QAAQ,uEAAG,EAAE;EAAA,OAAKJ,aAAI,CAACC,IAAI,CAACF,WAAW,EAAE,EAAEK,QAAQ,CAAC;AAAA;AAAA;AACtE,IAAMC,QAAQ,GAAID,QAAgB,IAAKE,EAAE,CAACC,YAAY,CAACH,QAAQ,EAAEP,IAAI,CAAC;AAAA;AAQtE,IAAMW,UAAU,GAAG,SAAbA,UAAU,GAAmC;EAAA,IAA/BC,QAAQ,uEAAG,EAAE;EACtC,IAAAC,cAAM,GAAE;EACR,IAAMC,QAAQ,GAAG,eAAe;EAChCF,QAAQ,GAAGA,QAAQ,IAAIV,WAAW,EAAE;EACpC,IAAIa,QAAQ,GAAGC,OAAO,CAACC,GAAG,CAACC,aAAa,IAAIZ,QAAQ,CAAC,YAAY,CAAC;EAClE,IAAMa,QAAQ,GAAGb,QAAQ,CAAC,OAAO,CAAC;EAClC,IAAMc,QAAQ,aAAMD,QAAQ,SAAGL,QAAQ,CAAE;EACzC,IAAMO,QAAQ,GAAGC,IAAI,CAACC,KAAK,CAACd,EAAE,CAACC,YAAY,CAACU,QAAQ,EAAEpB,IAAI,CAAC,CAAC;EAC5D,IAAIwB,OAAO,aAAMZ,QAAQ,SAAGS,QAAQ,CAACI,OAAO,CAAE;EAG9C,IAAI,CAAChB,EAAE,CAACiB,UAAU,CAACX,QAAQ,CAAC,EAAEA,QAAQ,GAAG,EAAE;EAC3C,IAAI,CAACN,EAAE,CAACiB,UAAU,CAACF,OAAO,CAAC,EAAEA,OAAO,GAAG,EAAE;EAEzC,OAAO;IACLJ,QAAQ;IACRL,QAAQ;IACRH,QAAQ;IACRS,QAAQ;IACRG,OAAO;IACPL;EACF,CAAC;AACH,CAAC;AAAA"}
|