New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

transposit

Package Overview
Dependencies
Maintainers
6
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

transposit - npm Package Compare versions

Comparing version 1.0.1 to 2.0.0-rc1

dist/types/__tests__/utils.test.d.ts

1179

dist/bundle.dev.js

@@ -84,2 +84,262 @@ (function webpackUniversalModuleDefinition(root, factory) {

/***/ "./src/Environment.ts":
/*!****************************!*\
!*** ./src/Environment.ts ***!
\****************************/
/*! exports provided: Environment */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Environment", function() { return Environment; });
/*
* Copyright 2019 Transposit Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (undefined && undefined.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var Environment = /** @class */ (function () {
function Environment(transposit) {
this.transposit = transposit;
}
Environment.prototype.get = function (key) {
return __awaiter(this, void 0, void 0, function () {
var queryParams;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
queryParams = { keyName: key };
return [4 /*yield*/, this.transposit.makeCallJson("GET", "/api/v1/env/value", {
queryParams: queryParams,
})];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
};
return Environment;
}());
/***/ }),
/***/ "./src/Operation.ts":
/*!**************************!*\
!*** ./src/Operation.ts ***!
\**************************/
/*! exports provided: OperationError */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OperationError", function() { return OperationError; });
/* harmony import */ var _errors_APIError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./errors/APIError */ "./src/errors/APIError.ts");
/*
* Copyright 2018, 2019 Transposit Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __extends = (undefined && undefined.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var OperationError = /** @class */ (function (_super) {
__extends(OperationError, _super);
function OperationError(log, response) {
var _this = this;
var exceptionLog = log.result.exceptionLog;
var message;
if (!exceptionLog || !exceptionLog.message) {
message = "A problem occurred when processing this operation.";
}
else {
message = exceptionLog.message;
}
_this = _super.call(this, message, response) || this;
_this.requestId = log.requestId;
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
Object.setPrototypeOf(_this, OperationError.prototype);
return _this;
}
return OperationError;
}(_errors_APIError__WEBPACK_IMPORTED_MODULE_0__["APIError"]));
/***/ }),
/***/ "./src/Stash.ts":
/*!**********************!*\
!*** ./src/Stash.ts ***!
\**********************/
/*! exports provided: Stash */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Stash", function() { return Stash; });
/*
* Copyright 2019 Transposit Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (undefined && undefined.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var Stash = /** @class */ (function () {
function Stash(transposit) {
this.transposit = transposit;
}
Stash.prototype.listKeys = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, this.transposit.makeCallJson("GET", "/api/v1/stash/keys")];
});
});
};
Stash.prototype.get = function (key) {
return __awaiter(this, void 0, void 0, function () {
var queryParams;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
queryParams = { keyName: key };
return [4 /*yield*/, this.transposit.makeCallJson("GET", "/api/v1/stash/value", { queryParams: queryParams })];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
};
Stash.prototype.put = function (key, value) {
return __awaiter(this, void 0, void 0, function () {
var queryParams;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
queryParams = { keyName: key };
return [4 /*yield*/, this.transposit.makeCall("POST", "/api/v1/stash/value", {
queryParams: queryParams,
body: value,
})];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
return Stash;
}());
/***/ }),
/***/ "./src/Transposit.ts":

@@ -89,3 +349,3 @@ /*!***************************!*\

\***************************/
/*! exports provided: LOCAL_STORAGE_KEY, Transposit */
/*! exports provided: Transposit */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

@@ -95,4 +355,10 @@

__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LOCAL_STORAGE_KEY", function() { return LOCAL_STORAGE_KEY; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Transposit", function() { return Transposit; });
/* harmony import */ var ___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! . */ "./src/index.ts");
/* harmony import */ var _errors_APIError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./errors/APIError */ "./src/errors/APIError.ts");
/* harmony import */ var _errors_SDKError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./errors/SDKError */ "./src/errors/SDKError.ts");
/* harmony import */ var _signin_pkce_helper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./signin/pkce-helper */ "./src/signin/pkce-helper.ts");
/* harmony import */ var _signin_token__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./signin/token */ "./src/signin/token.ts");
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils */ "./src/utils.ts");
/* harmony import */ var _utils_tr_fetch__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./utils/tr-fetch */ "./src/utils/tr-fetch.ts");
/*

@@ -148,13 +414,15 @@ * Copyright 2018, 2019 Transposit Corporation. All Rights Reserved.

};
// https://my-app.transposit.io?clientJwt=...needKeys=... -> https://my-app.transposit.io
function hereWithoutSearch() {
return "" + window.location.origin + window.location.pathname;
}
var LOCAL_STORAGE_KEY = "TRANSPOSIT_SESSION";
var Transposit = /** @class */ (function () {
function Transposit(hostedAppOrigin) {
if (hostedAppOrigin === void 0) { hostedAppOrigin = ""; }
this.hostedAppOrigin = hostedAppOrigin;
this.claims = null;
this.claims = this.loadClaims();
this.hostedAppOrigin = Object(_utils__WEBPACK_IMPORTED_MODULE_5__["chompSlash"])(hostedAppOrigin);
this.accessToken = null;
this.load();
}

@@ -165,93 +433,72 @@ Transposit.prototype.uri = function (path) {

};
Transposit.prototype.loadClaims = function () {
var claimsJSON = localStorage.getItem(LOCAL_STORAGE_KEY);
if (!claimsJSON) {
return null;
Transposit.prototype.load = function () {
this.accessToken = Object(_signin_token__WEBPACK_IMPORTED_MODULE_4__["loadAccessToken"])();
};
Transposit.prototype.assertIsSignedIn = function () {
if (!this.accessToken) {
throw new _errors_SDKError__WEBPACK_IMPORTED_MODULE_2__["SDKError"]("This method can only be called if the user is signed in");
}
var claims;
try {
claims = JSON.parse(claimsJSON);
}
catch (err) {
return null;
}
if (!this.checkClaimsValid(claims)) {
return null;
}
return claims;
};
Transposit.prototype.persistClaims = function (claimsJSON) {
localStorage.setItem(LOCAL_STORAGE_KEY, claimsJSON);
Transposit.prototype.isSignedIn = function () {
return this.accessToken !== null;
};
Transposit.prototype.clearClaims = function () {
localStorage.removeItem(LOCAL_STORAGE_KEY);
Transposit.prototype.signIn = function (redirectUri, provider) {
return __awaiter(this, void 0, void 0, function () {
var codeChallenge, params;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, Object(_signin_pkce_helper__WEBPACK_IMPORTED_MODULE_3__["pushCodeVerifier"])()];
case 1:
codeChallenge = _a.sent();
params = new URLSearchParams();
params.append("scope", "openid app");
params.append("response_type", "code");
params.append("client_id", "sdk");
params.append("redirect_uri", redirectUri);
params.append("prompt", "login");
params.append("code_challenge", codeChallenge);
params.append("code_challenge_method", "S256");
if (provider) {
params.append("provider", provider);
}
window.location.href = this.uri("/login/authorize?" + params.toString());
return [2 /*return*/];
}
});
});
};
Transposit.prototype.checkClaimsValid = function (claims) {
var expiration = claims.exp * 1000;
var now = Date.now();
return expiration > now;
Transposit.prototype.handleSignIn = function () {
return __awaiter(this, void 0, void 0, function () {
var searchParams, code, codeVerifier, headers, body, tokenResponse;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
searchParams = new URLSearchParams(window.location.search);
if (!searchParams.has("code")) {
throw new _errors_SDKError__WEBPACK_IMPORTED_MODULE_2__["SDKError"]("code query parameter could not be found. This method should only be called after redirection during sign-in.");
}
code = searchParams.get("code");
codeVerifier = Object(_signin_pkce_helper__WEBPACK_IMPORTED_MODULE_3__["popCodeVerifier"])();
headers = { "Content-Type": "application/x-www-form-urlencoded" };
body = {
grant_type: "authorization_code",
code: code,
redirect_uri: Object(_utils__WEBPACK_IMPORTED_MODULE_5__["hereWithoutSearch"])(),
code_verifier: codeVerifier,
};
return [4 /*yield*/, this.makeCallJson("POST", "/login/authorize/token", { headers: headers, body: body })];
case 1:
tokenResponse = _a.sent();
// Perform sign-in
Object(_signin_token__WEBPACK_IMPORTED_MODULE_4__["persistAccessToken"])(tokenResponse.access_token);
this.accessToken = tokenResponse.access_token;
// Return to indicate sign-in success
return [2 /*return*/, { needsKeys: tokenResponse.needs_keys }];
}
});
});
};
Transposit.prototype.assertLoggedIn = function () {
if (this.claims === null) {
throw new Error("No client claims found.");
}
};
Transposit.prototype.isLoggedIn = function () {
return this.claims !== null;
};
Transposit.prototype.handleLogin = function (callback) {
// Read query parameters
var searchParams = new URLSearchParams(window.location.search);
if (!searchParams.has("clientJwt")) {
throw new Error("clientJwt query parameter could not be found. This method should only be called after redirection during login.");
}
var clientJwtString = searchParams.get("clientJwt");
if (!searchParams.has("needsKeys")) {
throw new Error("needsKeys query parameter could not be found. This is unexpected.");
}
var needsKeys = searchParams.get("needsKeys") === "true";
// Parse JWT string
var jwtParts = clientJwtString.split(".");
if (jwtParts.length !== 3) {
throw new Error("clientJwt query parameter does not appear to be a valid JWT string. This method should only be called after redirection during login.");
}
var claimsJSON;
try {
claimsJSON = atob(jwtParts[1]);
}
catch (err) {
throw new Error("clientJwt query parameter does not appear to be a valid JWT string. This method should only be called after redirection during login.");
}
var claims;
try {
claims = JSON.parse(claimsJSON);
}
catch (err) {
throw new Error("clientJwt query parameter does not appear to be a valid JWT string. This method should only be called after redirection during login.");
}
if (!this.checkClaimsValid(claims)) {
throw new Error("clientJwt query parameter does not appear to be a valid JWT string. clientJwt is expired.");
}
// Persist claims. Login has succeeded.
this.claims = claims;
this.persistClaims(claimsJSON);
// Perform callback or default path replacement
if (callback) {
if (typeof callback !== "function") {
throw new Error("Provided callback is not a function.");
}
callback({ needsKeys: needsKeys });
}
else {
if (needsKeys) {
window.location.href = this.settingsUri(hereWithoutSearch());
}
else {
window.history.replaceState({}, document.title, window.location.pathname);
}
}
};
Transposit.prototype.logOut = function (redirectUri) {
this.clearClaims();
this.claims = null;
Transposit.prototype.signOut = function (redirectUri) {
this.accessToken = null;
Object(_signin_token__WEBPACK_IMPORTED_MODULE_4__["clearPersistedData"])();
window.location.href = this.uri("/logout?redirectUri=" + encodeURIComponent(redirectUri));

@@ -262,57 +509,228 @@ };

};
Transposit.prototype.startLoginUri = function (redirectUri, provider) {
var params = new URLSearchParams();
params.append("redirectUri", redirectUri || window.location.href);
if (provider) {
params.append("provider", provider);
}
return this.uri("/login/accounts?" + params.toString());
Object.defineProperty(Transposit.prototype, "stash", {
get: function () {
return new ___WEBPACK_IMPORTED_MODULE_0__["Stash"](this);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transposit.prototype, "env", {
get: function () {
return new ___WEBPACK_IMPORTED_MODULE_0__["Environment"](this);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transposit.prototype, "userSetting", {
get: function () {
return new ___WEBPACK_IMPORTED_MODULE_0__["UserSetting"](this);
},
enumerable: true,
configurable: true
});
Transposit.prototype.loadUser = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.assertIsSignedIn();
return [4 /*yield*/, this.makeCallJson("GET", "/api/v1/user")];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
};
// Deprecated in favor of settingsUri
Transposit.prototype.getConnectLocation = function (redirectUri) {
return this.settingsUri(redirectUri);
Transposit.prototype.run = function (operationId, parameters) {
if (parameters === void 0) { parameters = {}; }
return __awaiter(this, void 0, void 0, function () {
var response, log;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.makeCall("POST", "/api/v1/execute/" + operationId, { body: { parameters: parameters } })];
case 1:
response = _a.sent();
return [4 /*yield*/, extractJson(response)];
case 2:
log = _a.sent();
if (log.status !== "SUCCESS") {
throw new ___WEBPACK_IMPORTED_MODULE_0__["OperationError"](log, response);
}
return [2 /*return*/, new EndRequestLogResponse(log, response)];
}
});
});
};
// Deprecated in favor of startLoginUri
Transposit.prototype.getGoogleLoginLocation = function (redirectUri) {
return this.startLoginUri(redirectUri, "google");
Transposit.prototype.makeCallJson = function (method, path, httpParams) {
if (httpParams === void 0) { httpParams = {}; }
return __awaiter(this, void 0, void 0, function () {
var response;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.makeCall(method, path, httpParams)];
case 1:
response = _a.sent();
return [2 /*return*/, extractJson(response)];
}
});
});
};
// Deprecated
Transposit.prototype.getLoginLocation = function () {
return this.uri("/login");
Transposit.prototype.makeCall = function (method, path, _a) {
var _b = _a === void 0 ? {} : _a, queryParams = _b.queryParams, body = _b.body, headers = _b.headers;
return __awaiter(this, void 0, void 0, function () {
var url, bodyEncoder, response;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
if (!headers) {
headers = {
"Content-Type": "application/json",
};
if (this.accessToken) {
headers.Authorization = "Bearer " + this.accessToken;
}
}
url = new URL(path, this.hostedAppOrigin);
if (queryParams != null) {
Object.keys(queryParams).forEach(function (key) {
return url.searchParams.append(key, queryParams[key]);
});
}
if (headers["Content-Type"] === "application/x-www-form-urlencoded") {
bodyEncoder = _utils__WEBPACK_IMPORTED_MODULE_5__["formUrlEncode"];
}
else {
bodyEncoder = JSON.stringify;
}
return [4 /*yield*/, Object(_utils_tr_fetch__WEBPACK_IMPORTED_MODULE_6__["trfetch"])(url.href, Object.assign({ method: method, headers: headers }, body === null ? null : { body: bodyEncoder(body) }))];
case 1:
response = _c.sent();
return [2 /*return*/, response];
}
});
});
};
Transposit.prototype.getUserEmail = function () {
this.assertLoggedIn();
return this.claims.email;
return Transposit;
}());
function extractJson(response) {
return response.json().then(function (x) { return x; }, function () {
throw new _errors_APIError__WEBPACK_IMPORTED_MODULE_1__["APIError"]("Failed to read response body", response);
});
}
var EndRequestLogResponse = /** @class */ (function () {
function EndRequestLogResponse(log, response) {
this.requestId = log.requestId;
var logResults = log.result.results;
if (!logResults) {
throw new _errors_APIError__WEBPACK_IMPORTED_MODULE_1__["APIError"]("API returned an unexpected response schema", response);
}
this.results = logResults;
}
Object.defineProperty(EndRequestLogResponse.prototype, "value", {
get: function () {
if (this.results.length === 0) {
throw new Error("Operation did not return a value");
}
return this.results[0];
},
enumerable: true,
configurable: true
});
return EndRequestLogResponse;
}());
/***/ }),
/***/ "./src/UserSetting.ts":
/*!****************************!*\
!*** ./src/UserSetting.ts ***!
\****************************/
/*! exports provided: UserSetting */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UserSetting", function() { return UserSetting; });
/*
* Copyright 2019 Transposit Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (undefined && undefined.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var UserSetting = /** @class */ (function () {
function UserSetting(transposit) {
this.transposit = transposit;
}
UserSetting.prototype.get = function (key) {
return __awaiter(this, void 0, void 0, function () {
var queryParams;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
queryParams = { keyName: key };
return [4 /*yield*/, this.transposit.makeCallJson("GET", "/api/v1/user_setting/value", { queryParams: queryParams })];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
};
Transposit.prototype.getUserName = function () {
this.assertLoggedIn();
return this.claims.name;
};
Transposit.prototype.runOperation = function (operationId, params) {
if (params === void 0) { params = {}; }
UserSetting.prototype.put = function (key, value) {
return __awaiter(this, void 0, void 0, function () {
var headers, response;
var queryParams;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
headers = {
"Content-Type": "application/json",
};
if (this.claims) {
headers["X-PUBLIC-TOKEN"] = this.claims.publicToken;
}
return [4 /*yield*/, fetch(this.uri("/api/v1/execute/" + operationId), {
credentials: "include",
method: "POST",
headers: headers,
body: JSON.stringify({
parameters: params,
}),
queryParams = { keyName: key };
return [4 /*yield*/, this.transposit.makeCall("POST", "/api/v1/user_setting/value", {
queryParams: queryParams,
body: value,
})];
case 1:
response = _a.sent();
if (!(response.status >= 200 && response.status < 300)) return [3 /*break*/, 3];
return [4 /*yield*/, response.json()];
case 2: return [2 /*return*/, (_a.sent())];
case 3: throw response;
_a.sent();
return [2 /*return*/];
}

@@ -322,3 +740,3 @@ });

};
return Transposit;
return UserSetting;
}());

@@ -330,2 +748,119 @@

/***/ "./src/errors/APIError.ts":
/*!********************************!*\
!*** ./src/errors/APIError.ts ***!
\********************************/
/*! exports provided: APIError */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "APIError", function() { return APIError; });
/* harmony import */ var _SDKError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./SDKError */ "./src/errors/SDKError.ts");
/*
* Copyright 2019 Transposit Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __extends = (undefined && undefined.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
/**
* An APIError is an SDKError that always includes the raw response object.
*/
var APIError = /** @class */ (function (_super) {
__extends(APIError, _super);
function APIError(message, response) {
var _this = _super.call(this, message) || this;
_this.name = "APIError";
_this.response = response;
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
Object.setPrototypeOf(_this, APIError.prototype);
return _this;
}
return APIError;
}(_SDKError__WEBPACK_IMPORTED_MODULE_0__["SDKError"]));
/***/ }),
/***/ "./src/errors/SDKError.ts":
/*!********************************!*\
!*** ./src/errors/SDKError.ts ***!
\********************************/
/*! exports provided: SDKError */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SDKError", function() { return SDKError; });
/*
* Copyright 2019 Transposit Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __extends = (undefined && undefined.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
/**
* An SDKError is an Error that always has a user-visible message.
*/
var SDKError = /** @class */ (function (_super) {
__extends(SDKError, _super);
function SDKError(message) {
var _this = _super.call(this, message) || this;
_this.name = "SDKError";
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
Object.setPrototypeOf(_this, SDKError.prototype);
return _this;
}
return SDKError;
}(Error));
/***/ }),
/***/ "./src/index.ts":

@@ -335,3 +870,3 @@ /*!**********************!*\

\**********************/
/*! exports provided: LOCAL_STORAGE_KEY, Transposit */
/*! exports provided: Environment, OperationError, Transposit, Stash, UserSetting */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

@@ -341,7 +876,17 @@

__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _Transposit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Transposit */ "./src/Transposit.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LOCAL_STORAGE_KEY", function() { return _Transposit__WEBPACK_IMPORTED_MODULE_0__["LOCAL_STORAGE_KEY"]; });
/* harmony import */ var _Environment__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Environment */ "./src/Environment.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Environment", function() { return _Environment__WEBPACK_IMPORTED_MODULE_0__["Environment"]; });
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Transposit", function() { return _Transposit__WEBPACK_IMPORTED_MODULE_0__["Transposit"]; });
/* harmony import */ var _Operation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Operation */ "./src/Operation.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OperationError", function() { return _Operation__WEBPACK_IMPORTED_MODULE_1__["OperationError"]; });
/* harmony import */ var _Transposit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Transposit */ "./src/Transposit.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Transposit", function() { return _Transposit__WEBPACK_IMPORTED_MODULE_2__["Transposit"]; });
/* harmony import */ var _Stash__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Stash */ "./src/Stash.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Stash", function() { return _Stash__WEBPACK_IMPORTED_MODULE_3__["Stash"]; });
/* harmony import */ var _UserSetting__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./UserSetting */ "./src/UserSetting.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "UserSetting", function() { return _UserSetting__WEBPACK_IMPORTED_MODULE_4__["UserSetting"]; });
/*

@@ -365,2 +910,346 @@ * Copyright 2018, 2019 Transposit Corporation. All Rights Reserved.

/***/ }),
/***/ "./src/signin/pkce-helper.ts":
/*!***********************************!*\
!*** ./src/signin/pkce-helper.ts ***!
\***********************************/
/*! exports provided: pushCodeVerifier, popCodeVerifier */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pushCodeVerifier", function() { return pushCodeVerifier; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "popCodeVerifier", function() { return popCodeVerifier; });
/* harmony import */ var _errors_SDKError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../errors/SDKError */ "./src/errors/SDKError.ts");
/*
* Copyright 2019 Transposit Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// This code inspired by: https://developer.okta.com/blog/2019/05/01/is-the-oauth-implicit-flow-dead
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (undefined && undefined.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var PKCE_KEY = "TRANPOSIT_PKCE";
function generateRandomString() {
var array = new Uint32Array(28);
window.crypto.getRandomValues(array);
return Array.from(array, function (dec) { return ("0" + dec.toString(16)).substr(-2); }).join("");
}
function sha256(plain) {
var encoder = new TextEncoder();
var data = encoder.encode(plain);
return window.crypto.subtle.digest("SHA-256", data);
}
function base64urlencode(data) {
return btoa(String.fromCharCode.apply(null, new Uint8Array(data)))
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/, "");
}
function pkceChallengeFromVerifier(codeVerifier) {
return __awaiter(this, void 0, void 0, function () {
var hashed;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, sha256(codeVerifier)];
case 1:
hashed = _a.sent();
return [2 /*return*/, base64urlencode(hashed)];
}
});
});
}
function pushCodeVerifier() {
return __awaiter(this, void 0, void 0, function () {
var codeVerifier;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
codeVerifier = generateRandomString();
localStorage.setItem(PKCE_KEY, codeVerifier);
return [4 /*yield*/, pkceChallengeFromVerifier(codeVerifier)];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
}
function popCodeVerifier() {
var maybeCodeVerifier = localStorage.getItem(PKCE_KEY);
if (!maybeCodeVerifier) {
throw new _errors_SDKError__WEBPACK_IMPORTED_MODULE_0__["SDKError"]("PKCE state could not be found.");
}
localStorage.removeItem(PKCE_KEY);
return maybeCodeVerifier;
}
/***/ }),
/***/ "./src/signin/token.ts":
/*!*****************************!*\
!*** ./src/signin/token.ts ***!
\*****************************/
/*! exports provided: persistAccessToken, loadAccessToken, clearPersistedData */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "persistAccessToken", function() { return persistAccessToken; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadAccessToken", function() { return loadAccessToken; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clearPersistedData", function() { return clearPersistedData; });
/*
* Copyright 2019 Transposit Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Ensure no conflict with settings page session
var ACCESS_TOKEN_KEY = "TRANSPOSIT_ACCESS_TOKEN";
function extractClaims(accessToken) {
return JSON.parse(atob(accessToken.split(".")[1]));
}
function areClaimsValid(claims) {
var expiration = claims.exp * 1000;
var now = Date.now();
return expiration > now;
}
function isAccessTokenValid(accessToken) {
var claims = null;
try {
claims = extractClaims(accessToken);
}
catch (e) {
return false;
}
return areClaimsValid(claims);
}
function persistAccessToken(accessToken) {
localStorage.setItem(ACCESS_TOKEN_KEY, accessToken);
}
function loadAccessToken() {
var maybeAccessToken = localStorage.getItem(ACCESS_TOKEN_KEY);
if (maybeAccessToken && isAccessTokenValid(maybeAccessToken)) {
return maybeAccessToken;
}
return null;
}
function clearPersistedData() {
localStorage.removeItem(ACCESS_TOKEN_KEY);
}
/***/ }),
/***/ "./src/utils.ts":
/*!**********************!*\
!*** ./src/utils.ts ***!
\**********************/
/*! exports provided: chompSlash, hereWithoutSearch, formUrlEncode */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "chompSlash", function() { return chompSlash; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hereWithoutSearch", function() { return hereWithoutSearch; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "formUrlEncode", function() { return formUrlEncode; });
/*
* Copyright 2019 Transposit Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function chompSlash(string) {
return string.replace(/\/$/, "");
}
// https://my-app.transposit.io?clientJwt=...needKeys=... -> https://my-app.transposit.io
function hereWithoutSearch() {
return "" + window.location.origin + window.location.pathname;
}
function formUrlEncode(data) {
return Object.keys(data)
.map(function (key) {
return encodeURIComponent(key) + "=" + encodeURIComponent(data[key]);
})
.join("&");
}
/***/ }),
/***/ "./src/utils/tr-fetch.ts":
/*!*******************************!*\
!*** ./src/utils/tr-fetch.ts ***!
\*******************************/
/*! exports provided: trfetch, INTERNAL_ERROR_MESSAGE */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "trfetch", function() { return trfetch; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "INTERNAL_ERROR_MESSAGE", function() { return INTERNAL_ERROR_MESSAGE; });
/* harmony import */ var _errors_APIError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../errors/APIError */ "./src/errors/APIError.ts");
/*
* Copyright 2019 Transposit Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (undefined && undefined.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
/**
* trfetch() is a thin-wrapper around native fetch().
* It treats non-2XX responses as failures.
* It assumes response bodies should be parsed as JSON.
*/
function trfetch(input, init) {
return __awaiter(this, void 0, void 0, function () {
var response, error, body, e_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, fetch(input, init)];
case 1:
response = _a.sent();
if (!response.ok) return [3 /*break*/, 2];
return [2 /*return*/, response];
case 2:
error = void 0;
_a.label = 3;
case 3:
_a.trys.push([3, 5, , 6]);
return [4 /*yield*/, response.json()];
case 4:
body = _a.sent();
if (typeof body.message === "string") {
error = new _errors_APIError__WEBPACK_IMPORTED_MODULE_0__["APIError"](body.message, response);
}
else {
error = makeInternalError(response);
}
return [3 /*break*/, 6];
case 5:
e_1 = _a.sent();
error = makeInternalError(response);
return [3 /*break*/, 6];
case 6: throw error;
}
});
});
}
// @VisibleForTesting
var INTERNAL_ERROR_MESSAGE = "API call failed in an unexpected way. Try again.";
function makeInternalError(response) {
return new _errors_APIError__WEBPACK_IMPORTED_MODULE_0__["APIError"](INTERNAL_ERROR_MESSAGE, response);
}
/***/ })

@@ -367,0 +1256,0 @@

2

dist/bundle.prod.js

@@ -1,2 +0,2 @@

!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Transposit=e():t.Transposit=e()}(window,function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},n.r=function(t){Object.defineProperty(t,"__esModule",{value:!0})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){"use strict";n.r(e);var r=function(t,e,n,r){return new(n||(n=Promise))(function(o,i){function a(t){try{c(r.next(t))}catch(t){i(t)}}function s(t){try{c(r.throw(t))}catch(t){i(t)}}function c(t){t.done?o(t.value):new n(function(e){e(t.value)}).then(a,s)}c((r=r.apply(t,e||[])).next())})},o=function(t,e){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){a.label=i[1];break}if(6===i[0]&&a.label<o[1]){a.label=o[1],o=i;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(i);break}o[2]&&a.ops.pop(),a.trys.pop();continue}i=e.call(t,a)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,s])}}};var i=function(){function t(t){void 0===t&&(t=""),this.hostedAppOrigin=t,this.claims=null,this.claims=this.loadClaims()}return t.prototype.uri=function(t){return void 0===t&&(t=""),""+this.hostedAppOrigin+t},t.prototype.loadClaims=function(){var t,e=localStorage.getItem("TRANSPOSIT_SESSION");if(!e)return null;try{t=JSON.parse(e)}catch(t){return null}return this.checkClaimsValid(t)?t:null},t.prototype.persistClaims=function(t){localStorage.setItem("TRANSPOSIT_SESSION",t)},t.prototype.clearClaims=function(){localStorage.removeItem("TRANSPOSIT_SESSION")},t.prototype.checkClaimsValid=function(t){return 1e3*t.exp>Date.now()},t.prototype.assertLoggedIn=function(){if(null===this.claims)throw new Error("No client claims found.")},t.prototype.isLoggedIn=function(){return null!==this.claims},t.prototype.handleLogin=function(t){var e=new URLSearchParams(window.location.search);if(!e.has("clientJwt"))throw new Error("clientJwt query parameter could not be found. This method should only be called after redirection during login.");var n=e.get("clientJwt");if(!e.has("needsKeys"))throw new Error("needsKeys query parameter could not be found. This is unexpected.");var r,o,i="true"===e.get("needsKeys"),a=n.split(".");if(3!==a.length)throw new Error("clientJwt query parameter does not appear to be a valid JWT string. This method should only be called after redirection during login.");try{r=atob(a[1])}catch(t){throw new Error("clientJwt query parameter does not appear to be a valid JWT string. This method should only be called after redirection during login.")}try{o=JSON.parse(r)}catch(t){throw new Error("clientJwt query parameter does not appear to be a valid JWT string. This method should only be called after redirection during login.")}if(!this.checkClaimsValid(o))throw new Error("clientJwt query parameter does not appear to be a valid JWT string. clientJwt is expired.");if(this.claims=o,this.persistClaims(r),t){if("function"!=typeof t)throw new Error("Provided callback is not a function.");t({needsKeys:i})}else i?window.location.href=this.settingsUri(""+window.location.origin+window.location.pathname):window.history.replaceState({},document.title,window.location.pathname)},t.prototype.logOut=function(t){this.clearClaims(),this.claims=null,window.location.href=this.uri("/logout?redirectUri="+encodeURIComponent(t))},t.prototype.settingsUri=function(t){return this.uri("/settings?redirectUri="+encodeURIComponent(t||window.location.href))},t.prototype.startLoginUri=function(t,e){var n=new URLSearchParams;return n.append("redirectUri",t||window.location.href),e&&n.append("provider",e),this.uri("/login/accounts?"+n.toString())},t.prototype.getConnectLocation=function(t){return this.settingsUri(t)},t.prototype.getGoogleLoginLocation=function(t){return this.startLoginUri(t,"google")},t.prototype.getLoginLocation=function(){return this.uri("/login")},t.prototype.getUserEmail=function(){return this.assertLoggedIn(),this.claims.email},t.prototype.getUserName=function(){return this.assertLoggedIn(),this.claims.name},t.prototype.runOperation=function(t,e){return void 0===e&&(e={}),r(this,void 0,void 0,function(){var n,r;return o(this,function(o){switch(o.label){case 0:return n={"Content-Type":"application/json"},this.claims&&(n["X-PUBLIC-TOKEN"]=this.claims.publicToken),[4,fetch(this.uri("/api/v1/execute/"+t),{credentials:"include",method:"POST",headers:n,body:JSON.stringify({parameters:e})})];case 1:return(r=o.sent()).status>=200&&r.status<300?[4,r.json()]:[3,3];case 2:return[2,o.sent()];case 3:throw r}})})},t}();n.d(e,"LOCAL_STORAGE_KEY",function(){return"TRANSPOSIT_SESSION"}),n.d(e,"Transposit",function(){return i})}])});
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Transposit=e():t.Transposit=e()}(window,function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},n.r=function(t){Object.defineProperty(t,"__esModule",{value:!0})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){"use strict";n.r(e);var r,o=function(t,e,n,r){return new(n||(n=Promise))(function(o,i){function u(t){try{c(r.next(t))}catch(t){i(t)}}function a(t){try{c(r.throw(t))}catch(t){i(t)}}function c(t){t.done?o(t.value):new n(function(e){e(t.value)}).then(u,a)}c((r=r.apply(t,e||[])).next())})},i=function(t,e){var n,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;u;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return u.label++,{value:i[1],done:!1};case 5:u.label++,r=i[1],i=[0];continue;case 7:i=u.ops.pop(),u.trys.pop();continue;default:if(!(o=(o=u.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){u=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){u.label=i[1];break}if(6===i[0]&&u.label<o[1]){u.label=o[1],o=i;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(i);break}o[2]&&u.ops.pop(),u.trys.pop();continue}i=e.call(t,u)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}},u=function(){function t(t){this.transposit=t}return t.prototype.get=function(t){return o(this,void 0,void 0,function(){var e;return i(this,function(n){switch(n.label){case 0:return e={keyName:t},[4,this.transposit.makeCallJson("GET","/api/v1/env/value",{queryParams:e})];case 1:return[2,n.sent()]}})})},t}(),a=(r=function(t,e){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)},function(t,e){function n(){this.constructor=t}r(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}),c=function(t){function e(n){var r=t.call(this,n)||this;return r.name="SDKError",Object.setPrototypeOf(r,e.prototype),r}return a(e,t),e}(Error),s=function(){var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(e,n)};return function(e,n){function r(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}(),l=function(t){function e(n,r){var o=t.call(this,n)||this;return o.name="APIError",o.response=r,Object.setPrototypeOf(o,e.prototype),o}return s(e,t),e}(c),f=function(){var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(e,n)};return function(e,n){function r(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}(),p=function(t){function e(n,r){var o,i=this,u=n.result.exceptionLog;return o=u&&u.message?u.message:"A problem occurred when processing this operation.",(i=t.call(this,o,r)||this).requestId=n.requestId,Object.setPrototypeOf(i,e.prototype),i}return f(e,t),e}(l),h=function(t,e,n,r){return new(n||(n=Promise))(function(o,i){function u(t){try{c(r.next(t))}catch(t){i(t)}}function a(t){try{c(r.throw(t))}catch(t){i(t)}}function c(t){t.done?o(t.value):new n(function(e){e(t.value)}).then(u,a)}c((r=r.apply(t,e||[])).next())})},d=function(t,e){var n,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;u;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return u.label++,{value:i[1],done:!1};case 5:u.label++,r=i[1],i=[0];continue;case 7:i=u.ops.pop(),u.trys.pop();continue;default:if(!(o=(o=u.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){u=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){u.label=i[1];break}if(6===i[0]&&u.label<o[1]){u.label=o[1],o=i;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(i);break}o[2]&&u.ops.pop(),u.trys.pop();continue}i=e.call(t,u)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}},y="TRANPOSIT_PKCE";function b(t){return h(this,void 0,void 0,function(){return d(this,function(e){switch(e.label){case 0:return[4,(n=t,r=(new TextEncoder).encode(n),window.crypto.subtle.digest("SHA-256",r))];case 1:return[2,function(t){return btoa(String.fromCharCode.apply(null,new Uint8Array(t))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}(e.sent())]}var n,r})})}function v(){return h(this,void 0,void 0,function(){var t;return d(this,function(e){switch(e.label){case 0:return n=new Uint32Array(28),window.crypto.getRandomValues(n),t=Array.from(n,function(t){return("0"+t.toString(16)).substr(-2)}).join(""),localStorage.setItem(y,t),[4,b(t)];case 1:return[2,e.sent()]}var n})})}var w="TRANSPOSIT_ACCESS_TOKEN";function m(t){var e=null;try{e=function(t){return JSON.parse(atob(t.split(".")[1]))}(t)}catch(t){return!1}return function(t){return 1e3*t.exp>Date.now()}(e)}function g(t){return Object.keys(t).map(function(e){return encodeURIComponent(e)+"="+encodeURIComponent(t[e])}).join("&")}var k=function(t,e,n,r){return new(n||(n=Promise))(function(o,i){function u(t){try{c(r.next(t))}catch(t){i(t)}}function a(t){try{c(r.throw(t))}catch(t){i(t)}}function c(t){t.done?o(t.value):new n(function(e){e(t.value)}).then(u,a)}c((r=r.apply(t,e||[])).next())})},x=function(t,e){var n,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;u;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return u.label++,{value:i[1],done:!1};case 5:u.label++,r=i[1],i=[0];continue;case 7:i=u.ops.pop(),u.trys.pop();continue;default:if(!(o=(o=u.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){u=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){u.label=i[1];break}if(6===i[0]&&u.label<o[1]){u.label=o[1],o=i;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(i);break}o[2]&&u.ops.pop(),u.trys.pop();continue}i=e.call(t,u)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}};var S="API call failed in an unexpected way. Try again.";function _(t){return new l(S,t)}var O=function(t,e,n,r){return new(n||(n=Promise))(function(o,i){function u(t){try{c(r.next(t))}catch(t){i(t)}}function a(t){try{c(r.throw(t))}catch(t){i(t)}}function c(t){t.done?o(t.value):new n(function(e){e(t.value)}).then(u,a)}c((r=r.apply(t,e||[])).next())})},P=function(t,e){var n,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;u;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return u.label++,{value:i[1],done:!1};case 5:u.label++,r=i[1],i=[0];continue;case 7:i=u.ops.pop(),u.trys.pop();continue;default:if(!(o=(o=u.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){u=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){u.label=i[1];break}if(6===i[0]&&u.label<o[1]){u.label=o[1],o=i;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(i);break}o[2]&&u.ops.pop(),u.trys.pop();continue}i=e.call(t,u)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}},T=function(){function t(t){void 0===t&&(t=""),this.hostedAppOrigin=t.replace(/\/$/,""),this.accessToken=null,this.load()}return t.prototype.uri=function(t){return void 0===t&&(t=""),""+this.hostedAppOrigin+t},t.prototype.load=function(){var t;this.accessToken=(t=localStorage.getItem(w))&&m(t)?t:null},t.prototype.assertIsSignedIn=function(){if(!this.accessToken)throw new c("This method can only be called if the user is signed in")},t.prototype.isSignedIn=function(){return null!==this.accessToken},t.prototype.signIn=function(t,e){return O(this,void 0,void 0,function(){var n,r;return P(this,function(o){switch(o.label){case 0:return[4,v()];case 1:return n=o.sent(),(r=new URLSearchParams).append("scope","openid app"),r.append("response_type","code"),r.append("client_id","sdk"),r.append("redirect_uri",t),r.append("prompt","login"),r.append("code_challenge",n),r.append("code_challenge_method","S256"),e&&r.append("provider",e),window.location.href=this.uri("/login/authorize?"+r.toString()),[2]}})})},t.prototype.handleSignIn=function(){return O(this,void 0,void 0,function(){var t,e,n,r,o,i;return P(this,function(u){switch(u.label){case 0:if(!(t=new URLSearchParams(window.location.search)).has("code"))throw new c("code query parameter could not be found. This method should only be called after redirection during sign-in.");return e=t.get("code"),n=function(){var t=localStorage.getItem(y);if(!t)throw new c("PKCE state could not be found.");return localStorage.removeItem(y),t}(),r={"Content-Type":"application/x-www-form-urlencoded"},o={grant_type:"authorization_code",code:e,redirect_uri:""+window.location.origin+window.location.pathname,code_verifier:n},[4,this.makeCallJson("POST","/login/authorize/token",{headers:r,body:o})];case 1:return i=u.sent(),a=i.access_token,localStorage.setItem(w,a),this.accessToken=i.access_token,[2,{needsKeys:i.needs_keys}]}var a})})},t.prototype.signOut=function(t){this.accessToken=null,localStorage.removeItem(w),window.location.href=this.uri("/logout?redirectUri="+encodeURIComponent(t))},t.prototype.settingsUri=function(t){return this.uri("/settings?redirectUri="+encodeURIComponent(t||window.location.href))},Object.defineProperty(t.prototype,"stash",{get:function(){return new A(this)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"env",{get:function(){return new u(this)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"userSetting",{get:function(){return new G(this)},enumerable:!0,configurable:!0}),t.prototype.loadUser=function(){return O(this,void 0,void 0,function(){return P(this,function(t){switch(t.label){case 0:return this.assertIsSignedIn(),[4,this.makeCallJson("GET","/api/v1/user")];case 1:return[2,t.sent()]}})})},t.prototype.run=function(t,e){return void 0===e&&(e={}),O(this,void 0,void 0,function(){var n,r;return P(this,function(o){switch(o.label){case 0:return[4,this.makeCall("POST","/api/v1/execute/"+t,{body:{parameters:e}})];case 1:return[4,j(n=o.sent())];case 2:if("SUCCESS"!==(r=o.sent()).status)throw new p(r,n);return[2,new C(r,n)]}})})},t.prototype.makeCallJson=function(t,e,n){return void 0===n&&(n={}),O(this,void 0,void 0,function(){return P(this,function(r){switch(r.label){case 0:return[4,this.makeCall(t,e,n)];case 1:return[2,j(r.sent())]}})})},t.prototype.makeCall=function(t,e,n){var r=void 0===n?{}:n,o=r.queryParams,i=r.body,u=r.headers;return O(this,void 0,void 0,function(){var n,r;return P(this,function(a){switch(a.label){case 0:return u||(u={"Content-Type":"application/json"},this.accessToken&&(u.Authorization="Bearer "+this.accessToken)),n=new URL(e,this.hostedAppOrigin),null!=o&&Object.keys(o).forEach(function(t){return n.searchParams.append(t,o[t])}),r="application/x-www-form-urlencoded"===u["Content-Type"]?g:JSON.stringify,[4,function(t,e){return k(this,void 0,void 0,function(){var n,r,o;return x(this,function(i){switch(i.label){case 0:return[4,fetch(t,e)];case 1:return(n=i.sent()).ok?[2,n]:[3,2];case 2:r=void 0,i.label=3;case 3:return i.trys.push([3,5,,6]),[4,n.json()];case 4:return o=i.sent(),r="string"==typeof o.message?new l(o.message,n):_(n),[3,6];case 5:return i.sent(),r=_(n),[3,6];case 6:throw r}})})}(n.href,Object.assign({method:t,headers:u},null===i?null:{body:r(i)}))];case 1:return[2,a.sent()]}})})},t}();function j(t){return t.json().then(function(t){return t},function(){throw new l("Failed to read response body",t)})}var C=function(){function t(t,e){this.requestId=t.requestId;var n=t.result.results;if(!n)throw new l("API returned an unexpected response schema",e);this.results=n}return Object.defineProperty(t.prototype,"value",{get:function(){if(0===this.results.length)throw new Error("Operation did not return a value");return this.results[0]},enumerable:!0,configurable:!0}),t}(),I=function(t,e,n,r){return new(n||(n=Promise))(function(o,i){function u(t){try{c(r.next(t))}catch(t){i(t)}}function a(t){try{c(r.throw(t))}catch(t){i(t)}}function c(t){t.done?o(t.value):new n(function(e){e(t.value)}).then(u,a)}c((r=r.apply(t,e||[])).next())})},E=function(t,e){var n,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;u;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return u.label++,{value:i[1],done:!1};case 5:u.label++,r=i[1],i=[0];continue;case 7:i=u.ops.pop(),u.trys.pop();continue;default:if(!(o=(o=u.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){u=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){u.label=i[1];break}if(6===i[0]&&u.label<o[1]){u.label=o[1],o=i;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(i);break}o[2]&&u.ops.pop(),u.trys.pop();continue}i=e.call(t,u)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}},A=function(){function t(t){this.transposit=t}return t.prototype.listKeys=function(){return I(this,void 0,void 0,function(){return E(this,function(t){return[2,this.transposit.makeCallJson("GET","/api/v1/stash/keys")]})})},t.prototype.get=function(t){return I(this,void 0,void 0,function(){var e;return E(this,function(n){switch(n.label){case 0:return e={keyName:t},[4,this.transposit.makeCallJson("GET","/api/v1/stash/value",{queryParams:e})];case 1:return[2,n.sent()]}})})},t.prototype.put=function(t,e){return I(this,void 0,void 0,function(){var n;return E(this,function(r){switch(r.label){case 0:return n={keyName:t},[4,this.transposit.makeCall("POST","/api/v1/stash/value",{queryParams:n,body:e})];case 1:return r.sent(),[2]}})})},t}(),U=function(t,e,n,r){return new(n||(n=Promise))(function(o,i){function u(t){try{c(r.next(t))}catch(t){i(t)}}function a(t){try{c(r.throw(t))}catch(t){i(t)}}function c(t){t.done?o(t.value):new n(function(e){e(t.value)}).then(u,a)}c((r=r.apply(t,e||[])).next())})},q=function(t,e){var n,r,o,i,u={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(i){return function(a){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;u;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return u.label++,{value:i[1],done:!1};case 5:u.label++,r=i[1],i=[0];continue;case 7:i=u.ops.pop(),u.trys.pop();continue;default:if(!(o=(o=u.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){u=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){u.label=i[1];break}if(6===i[0]&&u.label<o[1]){u.label=o[1],o=i;break}if(o&&u.label<o[2]){u.label=o[2],u.ops.push(i);break}o[2]&&u.ops.pop(),u.trys.pop();continue}i=e.call(t,u)}catch(t){i=[6,t],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,a])}}},G=function(){function t(t){this.transposit=t}return t.prototype.get=function(t){return U(this,void 0,void 0,function(){var e;return q(this,function(n){switch(n.label){case 0:return e={keyName:t},[4,this.transposit.makeCallJson("GET","/api/v1/user_setting/value",{queryParams:e})];case 1:return[2,n.sent()]}})})},t.prototype.put=function(t,e){return U(this,void 0,void 0,function(){var n;return q(this,function(r){switch(r.label){case 0:return n={keyName:t},[4,this.transposit.makeCall("POST","/api/v1/user_setting/value",{queryParams:n,body:e})];case 1:return r.sent(),[2]}})})},t}();n.d(e,"Environment",function(){return u}),n.d(e,"OperationError",function(){return p}),n.d(e,"Transposit",function(){return T}),n.d(e,"Stash",function(){return A}),n.d(e,"UserSetting",function(){return G})}])});
//# sourceMappingURL=bundle.prod.map

@@ -0,1 +1,16 @@

/**
* Copyright 2018, 2019 Transposit Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {};

@@ -1,2 +0,6 @@

export * from "./EndRequestLog";
export * from "./Environment";
export * from "./Operation";
export * from "./Transposit";
export * from "./Stash";
export * from "./UserSetting";
export { User } from "./signin/user";
import "jest-localstorage-mock";
import "whatwg-fetch";

@@ -1,39 +0,38 @@

import { EndRequestLog } from ".";
export interface ClientClaims {
iss: string;
sub: string;
exp: number;
iat: number;
publicToken: string;
repository: string;
email: string;
name: string;
}
export interface OperationParameters {
[paramName: string]: string;
}
export declare const LOCAL_STORAGE_KEY = "TRANSPOSIT_SESSION";
import { Environment, OperationResponse, Stash, UserSetting } from ".";
import { User } from "./signin/user";
export declare class Transposit {
private hostedAppOrigin;
private claims;
private accessToken;
constructor(hostedAppOrigin?: string);
private uri;
private loadClaims;
private persistClaims;
private clearClaims;
private checkClaimsValid;
private assertLoggedIn;
isLoggedIn(): boolean;
handleLogin(callback?: (info: {
needsKeys: boolean;
}) => void): void;
logOut(redirectUri: string): void;
private load;
private assertIsSignedIn;
isSignedIn(): boolean;
signIn(redirectUri: string, provider?: "google" | "slack"): Promise<void>;
handleSignIn(): Promise<SignInSuccess>;
signOut(redirectUri: string): void;
settingsUri(redirectUri?: string): string;
startLoginUri(redirectUri?: string, provider?: "google" | "slack"): string;
getConnectLocation(redirectUri?: string): string;
getGoogleLoginLocation(redirectUri?: string): string;
getLoginLocation(): string;
getUserEmail(): string | null;
getUserName(): string | null;
runOperation(operationId: string, params?: OperationParameters): Promise<EndRequestLog>;
readonly stash: Stash;
readonly env: Environment;
readonly userSetting: UserSetting;
loadUser(): Promise<User>;
run<T>(operationId: string, parameters?: OperationParameters): Promise<OperationResponse<T>>;
makeCallJson<T>(method: string, path: string, httpParams?: HttpParams): Promise<T>;
makeCall(method: string, path: string, { queryParams, body, headers }?: HttpParams): Promise<Response>;
}
interface HttpParams {
body?: any;
headers?: {
[s: string]: string;
};
queryParams?: {
[s: string]: string;
};
}
export interface SignInSuccess {
needsKeys: boolean;
}
export interface OperationParameters {
[paramName: string]: string;
}
export {};

@@ -5,179 +5,2 @@ # Reference

## Handle login
`transposit.handleLogin([callback])`
Reads login information from the url and stores the claims object in localStorage for use in subsequent api calls. This is used after login redirect. This function redirects the user to authenticate if they are missing credentials.
If a callback is provided, it will be called after successful login.
**Returns** void
**Example**
```javascript
// call this when your handle-redirect page loads
try {
transposit.handleLogin(({ needsKeys }) => {
if (needsKeys === true) {
// user has not yet provided all credentials
}
});
} catch (err) {
// do nothing if this page is viewable when you are not logging in
}
```
## Check if logged in
`transposit.isLoggedIn()`
**Returns** (boolean): True if there exists login information (does not check if the token is expired).
## Log out
`transposit.logOut(redirectUri)`
Invalidates stored claims and clears them from localStorage. Redirects to Tranposit's logout page.
| Argument | Type | |
| :---------- | :----- | :---------------------------------------------------- |
| redirectUri | String | where to end up after successful logout |
**Returns**: void
## Run operation
`transposit.runOperation(operation, [params={}])`
Runs an operation.
| Argument | Type | |
| :---------- | :----- | :---------------------------------------------------- |
| operation | String | the name of the operation to be run |
| [params={}] | Object | an object containing any operation-defined parameters |
**Returns** (EndRequestLog): Returns the operation results and metadata about that result
**Example**
```javascript
transposit.runOperation("this.helloworld");
// => { status: "SUCCESS", result: { results: [{"Hello": "World"}] } }
transposit.runOperation("source.users", { id: params.userId });
// => { status: "ERROR", result: { exceptionLog: { message: "Failed to find user 123" } } }
```
## Get settings uri
`transposit.settingsUri([redirectUri=window.location.href])`
| Argument | Type | |
| :--------------------------------- | :----- | :---------------------------------------------------- |
| [redirectUri=window.location.href] | String | an optional param to specify an alternate redirectUri |
**Returns** (String): A url to redirect to for user settings.
**Example**
```javascript
transposit.settingsUri("https://localhost");
// => "https://hello-world-xyz12.transposit.io?redirectUri=https%3A%2F%2Flocalhost"
```
## Get URI to start login
`transposit.startLoginUri([redirectUri=window.location.href], [provider])`
| Argument | Type | |
| :--------------------------------- | :----- | :---------------------------------------------------- |
| [redirectUri=window.location.href] | String | an optional param to specify an alternate redirectUri |
| [provider] | String | an optional param to specify a login provider |
**Returns** (String): Location to start login.
**Example**
```javascript
transposit.startLoginUri("https://localhost");
// => "https://hello-world-xyz12.transposit.io/login/accounts?redirectUri=https%3A%2F%2Flocalhost"
```
## Get user name
`transposit.getUserName()`
Returns the full name of the logged-in user.
**Returns** (String): The full name of the logged-in user
**Example**
```javascript
transposit.getUserName();
// => "Pat Jones"
```
## Get user email
`transposit.getUserEmail()`
Returns the email address of the signed-in user.
**Returns** (String): The email address of the signed-in user
**Example**
```javascript
transposit.getUserEmail();
// => "patjones@gmail.com"
```
## EndRequestLog format
The full format of the return object for `transposit.runOperation`
```typescript
export interface EndRequestLog {
status: "SUCCESS" | "ERROR";
requestId: string;
timestamp: string;
serviceName: string;
serviceMaintainer: string;
operationId: string;
resultActionId?: string;
result: EndRequestLogResult;
}
export interface EndRequestLogResult {
results?: any[];
exceptionLog?: ExceptionLog;
}
export interface ExceptionLog {
message?: string;
stackTrace?: string;
exceptionClass?: string;
details?: ExceptionLogDetails;
}
export interface ExceptionLogDetails {
httpLog?: HttpLog;
scriptExceptionLog?: ScriptExceptionLog;
type: "HTTP" | "SCRIPTEXCEPTION" | "DETAILSNOTSET";
}
export interface HttpLog {
uri: string;
statusCode: number;
response?: string;
curlCommand?: string;
}
export interface ScriptExceptionLog {
line: number;
column?: number;
}
```
More coming soon!
{
"name": "transposit",
"version": "1.0.1",
"version": "2.0.0-rc1",
"author": "Transposit",

@@ -58,4 +58,5 @@ "description": "SDK for web apps using Transposit as a backend",

"webpack": "^4.1.1",
"webpack-cli": "^2.0.11"
"webpack-cli": "^2.0.11",
"whatwg-fetch": "^3.0.0"
}
}

@@ -22,3 +22,3 @@ <img src="https://www.transposit.com/img/transposit-logo-black.png" width="182px" alt="Transposit"/>

```html
<script src="https://unpkg.com/transposit@1.0.0/dist/bundle.prod.js"></script>
<script src="https://unpkg.com/transposit@2.0.0/dist/bundle.prod.js"></script>
```

@@ -46,11 +46,8 @@

transposit
.runOperation("myOperation")
.then(response => {
if (response.status !== "SUCCESS") {
throw response;
}
const results = response.result.results;
.run("myOperation")
.then(({results})) => {
// do it!
})
.catch(response => {
console.log(response);
.catch(error => {
console.log(error);
});

@@ -74,6 +71,3 @@ ```

function signin() {
window.location.href = transposit.startLoginUri(
// Specify where to redirect after sign-in is successful
`${window.location.origin}/handle-signin`
);
transposit.signIn(`${window.location.origin}/handle-signin`);
}

@@ -92,8 +86,6 @@ </script>

try {
transposit.handleLogin(() => {
// Specify where to redirect after sign-in completes
window.location.href = "/";
});
} catch (err) {
console.log(err);
await transposit.handleSignIn();
window.location.href = "/";
} catch (error) {
console.log(error);
window.location.href = "/signin";

@@ -104,9 +96,9 @@ }

### Signed-in routes
### Signed in routes
For all routes that require sign-in, check if the user is signed-in. Redirect to your sign-in page if they are not.
For all routes that require sign-in, check if the user is signed in. Redirect to your sign-in page if they are not.
```html
<script>
if (!transposit.isLoggedIn()) {
if (!transposit.isSignedIn()) {
window.location.href = "/signin";

@@ -125,3 +117,3 @@ }

function signout() {
transposit.logOut(`${window.location.origin}/signin`);
transposit.signOut(`${window.location.origin}/signin`);
}

@@ -128,0 +120,0 @@ </script>

@@ -1,2 +0,2 @@

/*
/**
* Copyright 2018, 2019 Transposit Corporation. All Rights Reserved.

@@ -18,26 +18,34 @@ *

import * as MockDate from "mockdate";
import { ClientClaims, LOCAL_STORAGE_KEY, Transposit } from "../Transposit";
import DoneCallback = jest.DoneCallback;
import { EndRequestLog } from "../EndRequestLog";
import { APIError } from "../errors/APIError";
import { OperationError, OperationResponse } from "../Operation";
import {
Claims,
loadAccessToken,
persistAccessToken,
TokenResponse,
} from "../signin/token";
import { User } from "../signin/user";
import {
createUnsignedJwt,
NOW,
NOW_MINUS_3_DAYS,
NOW_PLUS_3_DAYS,
setHref,
} from "../test/test-utils";
import { SignInSuccess, Transposit } from "../Transposit";
import { INTERNAL_ERROR_MESSAGE } from "../utils/tr-fetch";
jest.mock("../signin/pkce-helper");
const ARBYS_ORIGIN: string = "https://arbys-beef-xyz12.transposit.io";
function arbysUri(path: string = ""): string {
return `${ARBYS_ORIGIN}${path}`;
const BACKEND_ORIGIN: string = "https://arbys-beef-xyz12.transposit.io";
function backendUri(path: string = ""): string {
return `${BACKEND_ORIGIN}${path}`;
}
const NOW_MINUS_3_DAYS: number = 1521996119000;
const NOW: number = 1522255319000;
const NOW_PLUS_3_DAYS: number = 1522514519000;
function createUnsignedJwt(claims: ClientClaims): string {
const header: string = btoa(JSON.stringify({ alg: "none" }));
const body: string = btoa(JSON.stringify(claims));
return `${header}.${body}.`;
const FRONTEND_ORIGIN: string = "https://arbys-beef.com";
function frontendUri(path: string = ""): string {
return `${FRONTEND_ORIGIN}${path}`;
}
function setHref(origin: string, pathname: string, search: string): void {
window.location.href = `${origin}${pathname}${search}`;
(window.location as any).origin = origin; // origin is normally read-only, but not in tests :)
window.location.pathname = pathname;
window.location.search = search;
function makeSignedIn(accessToken: string) {
persistAccessToken(accessToken);
}

@@ -50,242 +58,531 @@

MockDate.set(NOW);
setHref(ARBYS_ORIGIN, "/", "");
setHref(FRONTEND_ORIGIN, "/", "");
});
const jplaceArbysClaims: ClientClaims = Object.freeze({
iss: ARBYS_ORIGIN,
sub: "jplace@transposit.com",
const user: User = {
name: "Kernel Sanders",
email: "sanders@kernel.com",
};
const claims: Claims = Object.freeze({
iss: BACKEND_ORIGIN,
sub: `google|${user.email}`,
exp: NOW_PLUS_3_DAYS / 1000,
iat: NOW_MINUS_3_DAYS / 1000,
publicToken: "thisisapublictoken",
repository: "jplace/arbys_beef",
email: "jplace@transposit.com",
name: "Jordan 'The Beef' Place",
});
const jplaceArbysJwt: string = createUnsignedJwt(jplaceArbysClaims);
const accessToken: string = createUnsignedJwt(claims);
describe("isLoggedIn", () => {
it("knows when you've just logged in", () => {
setHref(
ARBYS_ORIGIN,
"/",
`?clientJwt=${jplaceArbysJwt}&needsKeys=false`,
it("signs in", async () => {
expect.assertions(5);
{
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
await transposit.signIn(frontendUri("/handle-signin"));
expect(window.location.href).toEqual(
backendUri(
"/login/authorize?scope=openid+app&response_type=code&client_id=sdk&redirect_uri=https%3A%2F%2Farbys-beef.com%2Fhandle-signin&prompt=login&code_challenge=challenge-from-code-verifier&code_challenge_method=S256",
),
);
}
const transposit: Transposit = new Transposit();
transposit.handleLogin();
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(
new Response(
JSON.stringify({
access_token: accessToken,
needs_keys: false,
user: { name: "Farmer May", email: "may@transposit.com" },
} as TokenResponse),
),
),
);
expect(transposit.isLoggedIn()).toBe(true);
});
setHref(FRONTEND_ORIGIN, "/handle-signin", `?code=some-code-to-trade`);
{
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
const signInSuccess: SignInSuccess = await transposit.handleSignIn();
it("knows when you're logged out", () => {
const transposit: Transposit = new Transposit();
expect(signInSuccess).toEqual({ needsKeys: false });
expect(window.fetch as jest.Mock).toHaveBeenCalledWith(
"https://arbys-beef-xyz12.transposit.io/login/authorize/token",
{
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body:
"grant_type=authorization_code&code=some-code-to-trade&redirect_uri=https%3A%2F%2Farbys-beef.com%2Fhandle-signin&code_verifier=code-verifier",
},
);
expect(transposit.isSignedIn()).toBe(true);
}
expect(transposit.isLoggedIn()).toBe(false);
});
setHref(FRONTEND_ORIGIN, "/", "");
{
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
expect(transposit.isSignedIn()).toBe(true);
}
});
it("knows when your session expired", () => {
setHref(
ARBYS_ORIGIN,
"/",
`?clientJwt=${jplaceArbysJwt}&needsKeys=false`,
it("knows when you're signed out", () => {
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
expect(transposit.isSignedIn()).toBe(false);
});
it("knows when your session expired", () => {
makeSignedIn(accessToken);
let transposit: Transposit;
transposit = new Transposit(BACKEND_ORIGIN);
expect(transposit.isSignedIn()).toBe(true);
// 3. days. later...
MockDate.set((claims.exp + 60 * 60 * 24 * 3) * 1000);
transposit = new Transposit(BACKEND_ORIGIN);
expect(transposit.isSignedIn()).toBe(false);
});
it("starts sign-in with a specific provider", async () => {
expect.assertions(1);
const transposit: Transposit = new Transposit(`${BACKEND_ORIGIN}/`);
await transposit.signIn(frontendUri("/handle-signin"), "google");
expect(window.location.href).toEqual(
backendUri(
"/login/authorize?scope=openid+app&response_type=code&client_id=sdk&redirect_uri=https%3A%2F%2Farbys-beef.com%2Fhandle-signin&prompt=login&code_challenge=challenge-from-code-verifier&code_challenge_method=S256&provider=google",
),
);
});
it("can't complete sign-in without a code", async () => {
expect.assertions(1);
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
try {
await transposit.handleSignIn();
} catch (e) {
expect(e.message).toBe(
"code query parameter could not be found. This method should only be called after redirection during sign-in.",
);
}
});
let transposit: Transposit = new Transposit();
transposit.handleLogin();
it("can't complete sign-in if token endpoint returns 4XX", async () => {
expect.assertions(2);
// 3 days after expiration
MockDate.set((jplaceArbysClaims.exp + 60 * 60 * 24 * 3) * 1000);
transposit = new Transposit();
setHref(FRONTEND_ORIGIN, "/handle-signin", `?code=some-code-to-trade`);
expect(transposit.isLoggedIn()).toBe(false);
});
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(
new Response(null, { status: 400, statusText: "Bad Request" }),
),
);
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
try {
await transposit.handleSignIn();
} catch (e) {
expect(e).toBeInstanceOf(APIError);
expect(e.message).toBe(INTERNAL_ERROR_MESSAGE);
}
});
describe("handleLogin", () => {
it("calls replaceState", () => {
setHref(
ARBYS_ORIGIN,
"/",
`?clientJwt=${jplaceArbysJwt}&needsKeys=false`,
it("can't complete sign-in if token endpoint network errors", async () => {
expect.assertions(2);
setHref(FRONTEND_ORIGIN, "/handle-signin", `?code=some-code-to-trade`);
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.reject(new TypeError("Network error")),
);
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
try {
await transposit.handleSignIn();
} catch (e) {
expect(e).toBeInstanceOf(TypeError);
expect(e.message).toBe("Network error");
}
});
it("signs out", () => {
makeSignedIn(accessToken);
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
expect(transposit.isSignedIn()).toBe(true);
transposit.signOut(frontendUri("/login"));
expect(transposit.isSignedIn()).toBe(false);
expect(loadAccessToken()).toBeNull();
expect(window.location.href).toBe(
"https://arbys-beef-xyz12.transposit.io/logout?redirectUri=https%3A%2F%2Farbys-beef.com%2Flogin",
);
});
it("links to the settings page", () => {
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
expect(transposit.settingsUri(frontendUri("/success"))).toBe(
"https://arbys-beef-xyz12.transposit.io/settings?redirectUri=https%3A%2F%2Farbys-beef.com%2Fsuccess",
);
expect(transposit.settingsUri()).toBe(
"https://arbys-beef-xyz12.transposit.io/settings?redirectUri=https%3A%2F%2Farbys-beef.com%2F",
);
});
it("doesn't load a user if not signed in", async () => {
expect.assertions(1);
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
try {
await transposit.loadUser();
} catch (e) {
expect(e.message).toBe(
"This method can only be called if the user is signed in",
);
}
});
const transposit: Transposit = new Transposit();
transposit.handleLogin();
it("loads a user", async () => {
expect.assertions(2);
expect(JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)!)).toEqual(
jplaceArbysClaims,
makeSignedIn(accessToken);
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(new Response(JSON.stringify(user))),
);
const loadedUser: User = await transposit.loadUser();
expect(loadedUser).toEqual(user);
expect(window.fetch as jest.Mock).toHaveBeenCalledWith(
"https://arbys-beef-xyz12.transposit.io/api/v1/user",
{
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization:
"Bearer eyJhbGciOiJub25lIn0=.eyJpc3MiOiJodHRwczovL2FyYnlzLWJlZWYteHl6MTIudHJhbnNwb3NpdC5pbyIsInN1YiI6Imdvb2dsZXxzYW5kZXJzQGtlcm5lbC5jb20iLCJleHAiOjE1MjI1MTQ1MTksImlhdCI6MTUyMTk5NjExOX0=.",
},
},
);
});
describe("run", () => {
it("runs operation without sign-in", async () => {
expect.assertions(4);
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(
new Response(
JSON.stringify({
status: "SUCCESS",
requestId: "12345",
result: {
results: ["hello", "world"],
},
} as EndRequestLog),
),
),
);
expect(window.history.replaceState).toHaveBeenCalledWith(
{},
window.document.title,
"/",
const response: OperationResponse<string> = await transposit.run<string>(
"hello_world",
);
});
it("redirects when needs keys", () => {
setHref(ARBYS_ORIGIN, "/", `?clientJwt=${jplaceArbysJwt}&needsKeys=true`);
expect(response.requestId).toEqual("12345");
expect(response.results).toEqual(["hello", "world"]);
expect(response.value).toEqual("hello");
const transposit: Transposit = new Transposit();
transposit.handleLogin();
expect(JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)!)).toEqual(
jplaceArbysClaims,
expect(window.fetch as jest.Mock).toHaveBeenCalledWith(
"https://arbys-beef-xyz12.transposit.io/api/v1/execute/hello_world",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: '{"parameters":{}}',
},
);
expect(window.location.href).toEqual(
"/settings?redirectUri=https%3A%2F%2Farbys-beef-xyz12.transposit.io%2F",
);
});
it("calls callback", () => {
setHref(ARBYS_ORIGIN, "/", `?clientJwt=${jplaceArbysJwt}&needsKeys=true`);
it("runs an operation with sign-in", async () => {
expect.assertions(4);
const mockCallback = jest.fn();
makeSignedIn(accessToken);
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
const transposit: Transposit = new Transposit();
transposit.handleLogin(mockCallback);
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(
new Response(
JSON.stringify({
status: "SUCCESS",
requestId: "12345",
result: {
results: ["hello", "world"],
},
} as EndRequestLog),
),
),
);
expect(JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)!)).toEqual(
jplaceArbysClaims,
const response: OperationResponse<string> = await transposit.run<string>(
"hello_world",
);
expect(mockCallback).toHaveBeenCalledWith({ needsKeys: true });
expect(window.history.replaceState).not.toHaveBeenCalled();
});
it("throws if callback is not a function", (done: DoneCallback) => {
setHref(ARBYS_ORIGIN, "/", `?clientJwt=${jplaceArbysJwt}&needsKeys=true`);
expect(response.requestId).toEqual("12345");
expect(response.results).toEqual(["hello", "world"]);
expect(response.value).toEqual("hello");
const transposit: Transposit = new Transposit();
try {
transposit.handleLogin("string" as any);
done.fail();
} catch (err) {
expect(err.message).toContain("Provided callback is not a function.");
done();
}
expect(window.fetch as jest.Mock).toHaveBeenCalledWith(
"https://arbys-beef-xyz12.transposit.io/api/v1/execute/hello_world",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization:
"Bearer eyJhbGciOiJub25lIn0=.eyJpc3MiOiJodHRwczovL2FyYnlzLWJlZWYteHl6MTIudHJhbnNwb3NpdC5pbyIsInN1YiI6Imdvb2dsZXxzYW5kZXJzQGtlcm5lbC5jb20iLCJleHAiOjE1MjI1MTQ1MTksImlhdCI6MTUyMTk5NjExOX0=.",
},
body: '{"parameters":{}}',
},
);
});
it("throws without jwt", (done: DoneCallback) => {
setHref(ARBYS_ORIGIN, "/", "");
it("run an operation and throws APIError", async () => {
expect.assertions(2);
const transposit: Transposit = new Transposit();
makeSignedIn(accessToken);
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(
new Response(null, { status: 400, statusText: "Bad Request" }),
),
);
try {
transposit.handleLogin();
done.fail();
} catch (err) {
expect(err.message).toContain(
"clientJwt query parameter could not be found",
);
done();
await transposit.run<string>("hello_world");
} catch (e) {
expect(e).toBeInstanceOf(APIError);
expect(e.message).toEqual(INTERNAL_ERROR_MESSAGE);
}
});
it("throws without needsKeys", (done: DoneCallback) => {
setHref(ARBYS_ORIGIN, "/", `?clientJwt=${jplaceArbysJwt}`);
const badStatuses = [
"ERROR",
"CANCELLED",
"TIMEOUT",
"RESOURCELIMITEXCEEDED",
];
badStatuses.forEach(status => {
it(`run with ${status} throws OperationError`, async () => {
expect.assertions(4);
const transposit: Transposit = new Transposit();
try {
transposit.handleLogin();
done.fail();
} catch (err) {
expect(err.message).toContain(
"needsKeys query parameter could not be found. This is unexpected.",
makeSignedIn(accessToken);
const transposit: Transposit = new Transposit(BACKEND_ORIGIN);
const response: Response = new Response(
JSON.stringify({
status,
requestId: "12345",
result: {
exceptionLog: {
message: "myError",
},
},
} as EndRequestLog),
);
done();
}
});
function testInvalidJwt(done: DoneCallback, invalidJwt: string) {
setHref(ARBYS_ORIGIN, "/", `?clientJwt=${invalidJwt}&needsKeys=false`);
const transposit: Transposit = new Transposit();
try {
transposit.handleLogin();
done.fail();
} catch (err) {
expect(err.message).toContain(
"clientJwt query parameter does not appear to be a valid JWT string",
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(response),
);
done();
}
}
it("throws with invalid jwt (empty)", (done: DoneCallback) => {
testInvalidJwt(done, "");
try {
return await transposit.run<string>("hello_world");
} catch (e) {
expect(e).toBeInstanceOf(OperationError);
expect(e.message).toEqual("myError");
expect(e.response).toEqual(response);
expect(e.requestId).toEqual("12345");
}
return null;
});
});
});
it("throws with invalid jwt (not-properly formatted jwt)", (done: DoneCallback) => {
testInvalidJwt(done, "adsfasfdfd.fdsafadfsf");
});
it("deserializes good json in 2XX response", async () => {
expect.assertions(1);
it("throws with invalid jwt (not-base64 jwt)", (done: DoneCallback) => {
testInvalidJwt(done, "dffgdf--6667.fdsaf#f.");
});
const expected = { everything: "is", a: "okay!" };
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(new Response(JSON.stringify(expected), { status: 200 })),
);
it("throws with invalid jwt (not-json jwt)", (done: DoneCallback) => {
testInvalidJwt(
done,
`${btoa("{ not-=json: yeeeee")}.${btoa("{ not-=json: yeeeee")}.`,
const transposit = new Transposit(BACKEND_ORIGIN);
const actual = await transposit.makeCallJson<{}>("GET", "/endpoint");
expect(actual).toEqual(expected);
});
it("invalid json throws error", async () => {
expect.assertions(1);
const response = new Response("totaljunk", { status: 200 });
(window.fetch as jest.Mock).mockReturnValueOnce(Promise.resolve(response));
const transposit = new Transposit(BACKEND_ORIGIN);
return expect(
transposit.makeCallJson<{}>("GET", "/endpoint"),
).rejects.toThrow(new APIError("Failed to read response body", response));
});
describe("stash", () => {
it("stash get sends correct request", async () => {
expect.assertions(2);
const expected = "someString";
const response = new Response('"someString"');
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(response),
);
});
const transposit = new Transposit(BACKEND_ORIGIN);
it("throws with invalid jwt (expired)", (done: DoneCallback) => {
const expiredClaims = Object.assign({}, jplaceArbysClaims, {
exp: NOW_MINUS_3_DAYS / 1000,
});
testInvalidJwt(done, createUnsignedJwt(expiredClaims));
const actual = await transposit.stash.get("key");
expect(actual).toBe(expected);
expect(window.fetch as jest.Mock).toHaveBeenCalledWith(
"https://arbys-beef-xyz12.transposit.io/api/v1/stash/value?keyName=key",
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
},
);
});
});
describe("logout", () => {
let transposit: Transposit;
it("stash listKeys sends correct request", async () => {
expect.assertions(2);
const expected = ["a", "b", "c"];
const response = new Response(`["a", "b", "c"]`);
beforeEach(() => {
setHref(
ARBYS_ORIGIN,
"/",
`?clientJwt=${jplaceArbysJwt}&needsKeys=false`,
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(response),
);
transposit = new Transposit();
transposit.handleLogin();
const transposit = new Transposit(BACKEND_ORIGIN);
const actual = await transposit.stash.listKeys();
expect(actual).toEqual(expected);
expect(window.fetch as jest.Mock).toHaveBeenCalledWith(
"https://arbys-beef-xyz12.transposit.io/api/v1/stash/keys",
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
},
);
});
it("handles successful logout", () => {
transposit.logOut(arbysUri("/login"));
it("stash put sends correct request", async () => {
expect.assertions(1);
const response = new Response("");
expect(localStorage.getItem(LOCAL_STORAGE_KEY)).toBeNull();
expect(transposit.isLoggedIn()).toBe(false);
expect(window.location.href).toEqual(
"/logout?redirectUri=https%3A%2F%2Farbys-beef-xyz12.transposit.io%2Flogin",
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(response),
);
const transposit = new Transposit(BACKEND_ORIGIN);
await transposit.stash.put("key", "value");
expect(window.fetch as jest.Mock).toHaveBeenCalledWith(
"https://arbys-beef-xyz12.transposit.io/api/v1/stash/value?keyName=key",
{
method: "POST",
body: `"value"`,
headers: {
"Content-Type": "application/json",
},
},
);
});
});
describe("startLoginUri", () => {
it("returns the correct default location", () => {
const transposit: Transposit = new Transposit(ARBYS_ORIGIN);
describe("env", () => {
it("env get sends correct request", async () => {
expect.assertions(2);
const expected = "someString";
const response = new Response('"someString"');
expect(transposit.startLoginUri("https://altoids.com")).toEqual(
"https://arbys-beef-xyz12.transposit.io/login/accounts?redirectUri=https%3A%2F%2Faltoids.com",
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(response),
);
const transposit = new Transposit(BACKEND_ORIGIN);
const actual = await transposit.env.get<string>("key");
expect(actual).toBe(expected);
expect(window.fetch as jest.Mock).toHaveBeenCalledWith(
"https://arbys-beef-xyz12.transposit.io/api/v1/env/value?keyName=key",
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
},
);
});
});
it("returns the correct google location", () => {
const transposit: Transposit = new Transposit(ARBYS_ORIGIN);
describe("userSetting", () => {
it("userSetting get sends correct request", async () => {
expect.assertions(2);
const expected = "someString";
const response = new Response('"someString"');
expect(transposit.startLoginUri("https://altoids.com", "google")).toEqual(
"https://arbys-beef-xyz12.transposit.io/login/accounts?redirectUri=https%3A%2F%2Faltoids.com&provider=google",
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(response),
);
expect(transposit.getGoogleLoginLocation("https://altoids.com")).toEqual(
"https://arbys-beef-xyz12.transposit.io/login/accounts?redirectUri=https%3A%2F%2Faltoids.com&provider=google",
const transposit = new Transposit(BACKEND_ORIGIN);
const actual = await transposit.userSetting.get<string>("key");
expect(actual).toBe(expected);
expect(window.fetch as jest.Mock).toHaveBeenCalledWith(
"https://arbys-beef-xyz12.transposit.io/api/v1/user_setting/value?keyName=key",
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
},
);
});
it("returns the correct slack location", () => {
const transposit: Transposit = new Transposit(ARBYS_ORIGIN);
it("userSetting put sends correct request", async () => {
expect.assertions(1);
const response = new Response("");
expect(transposit.startLoginUri("https://altoids.com", "slack")).toEqual(
"https://arbys-beef-xyz12.transposit.io/login/accounts?redirectUri=https%3A%2F%2Faltoids.com&provider=slack",
(window.fetch as jest.Mock).mockReturnValueOnce(
Promise.resolve(response),
);
const transposit = new Transposit(BACKEND_ORIGIN);
await transposit.userSetting.put("key", "value");
expect(window.fetch as jest.Mock).toHaveBeenCalledWith(
"https://arbys-beef-xyz12.transposit.io/api/v1/user_setting/value?keyName=key",
{
method: "POST",
body: `"value"`,
headers: {
"Content-Type": "application/json",
},
},
);
});
});
});

@@ -17,3 +17,7 @@ /*

export * from "./EndRequestLog";
export * from "./Environment";
export * from "./Operation";
export * from "./Transposit";
export * from "./Stash";
export * from "./UserSetting";
export { User } from "./signin/user";

@@ -18,2 +18,3 @@ /*

import "jest-localstorage-mock";
import "whatwg-fetch"; // polyfill for Response class

@@ -20,0 +21,0 @@ // Most hilarious work around courtesy of https://github.com/facebook/jest/issues/5124

@@ -17,31 +17,32 @@ /*

import { EndRequestLog } from ".";
import {
Environment,
OperationError,
OperationResponse,
Stash,
UserSetting,
} from ".";
import { EndRequestLog } from "./EndRequestLog";
import { APIError } from "./errors/APIError";
import { SDKError } from "./errors/SDKError";
import { popCodeVerifier, pushCodeVerifier } from "./signin/pkce-helper";
import {
clearPersistedData,
loadAccessToken,
persistAccessToken,
TokenResponse,
} from "./signin/token";
import { User } from "./signin/user";
import { chompSlash, formUrlEncode, hereWithoutSearch } from "./utils";
import { trfetch } from "./utils/tr-fetch";
export interface ClientClaims {
iss: string; // issuer
sub: string; // subject
exp: number; // expiration
iat: number; // issuedAt
publicToken: string;
repository: string;
email: string;
name: string;
}
export class Transposit {
private hostedAppOrigin: string;
private accessToken: string | null;
export interface OperationParameters {
[paramName: string]: string;
}
constructor(hostedAppOrigin: string = "") {
this.hostedAppOrigin = chompSlash(hostedAppOrigin);
this.accessToken = null;
// https://my-app.transposit.io?clientJwt=...needKeys=... -> https://my-app.transposit.io
function hereWithoutSearch(): string {
return `${window.location.origin}${window.location.pathname}`;
}
export const LOCAL_STORAGE_KEY = "TRANSPOSIT_SESSION";
export class Transposit {
private claims: ClientClaims | null = null;
constructor(private hostedAppOrigin: string = "") {
this.claims = this.loadClaims();
this.load();
}

@@ -53,47 +54,39 @@

private loadClaims(): ClientClaims | null {
const claimsJSON = localStorage.getItem(LOCAL_STORAGE_KEY);
if (!claimsJSON) {
return null;
}
private load(): void {
this.accessToken = loadAccessToken();
}
let claims: ClientClaims;
try {
claims = JSON.parse(claimsJSON);
} catch (err) {
return null;
private assertIsSignedIn(): void {
if (!this.accessToken) {
throw new SDKError(
"This method can only be called if the user is signed in",
);
}
if (!this.checkClaimsValid(claims)) {
return null;
}
return claims;
}
private persistClaims(claimsJSON: string): void {
localStorage.setItem(LOCAL_STORAGE_KEY, claimsJSON);
isSignedIn(): boolean {
return this.accessToken !== null;
}
private clearClaims(): void {
localStorage.removeItem(LOCAL_STORAGE_KEY);
}
async signIn(
redirectUri: string,
provider?: "google" | "slack",
): Promise<void> {
const codeChallenge = await pushCodeVerifier();
private checkClaimsValid(claims: ClientClaims): boolean {
const expiration = claims.exp * 1000;
const now = Date.now();
return expiration > now;
}
private assertLoggedIn(): void {
if (this.claims === null) {
throw new Error("No client claims found.");
const params = new URLSearchParams();
params.append("scope", "openid app");
params.append("response_type", "code");
params.append("client_id", "sdk");
params.append("redirect_uri", redirectUri);
params.append("prompt", "login");
params.append("code_challenge", codeChallenge);
params.append("code_challenge_method", "S256");
if (provider) {
params.append("provider", provider);
}
window.location.href = this.uri(`/login/authorize?${params.toString()}`);
}
isLoggedIn(): boolean {
return this.claims !== null;
}
handleLogin(callback?: (info: { needsKeys: boolean }) => void): void {
async handleSignIn(): Promise<SignInSuccess> {
// Read query parameters

@@ -103,74 +96,39 @@

if (!searchParams.has("clientJwt")) {
throw new Error(
"clientJwt query parameter could not be found. This method should only be called after redirection during login.",
if (!searchParams.has("code")) {
throw new SDKError(
"code query parameter could not be found. This method should only be called after redirection during sign-in.",
);
}
const clientJwtString = searchParams.get("clientJwt")!;
const code = searchParams.get("code")!;
if (!searchParams.has("needsKeys")) {
throw new Error(
"needsKeys query parameter could not be found. This is unexpected.",
);
}
const needsKeys = searchParams.get("needsKeys")! === "true";
// Exchange code for access_token
// Parse JWT string
const codeVerifier = popCodeVerifier();
const jwtParts: string[] = clientJwtString.split(".");
if (jwtParts.length !== 3) {
throw new Error(
"clientJwt query parameter does not appear to be a valid JWT string. This method should only be called after redirection during login.",
);
}
let claimsJSON: string;
try {
claimsJSON = atob(jwtParts[1]);
} catch (err) {
throw new Error(
"clientJwt query parameter does not appear to be a valid JWT string. This method should only be called after redirection during login.",
);
}
let claims: ClientClaims;
try {
claims = JSON.parse(claimsJSON);
} catch (err) {
throw new Error(
"clientJwt query parameter does not appear to be a valid JWT string. This method should only be called after redirection during login.",
);
}
if (!this.checkClaimsValid(claims)) {
throw new Error(
"clientJwt query parameter does not appear to be a valid JWT string. clientJwt is expired.",
);
}
const headers = { "Content-Type": "application/x-www-form-urlencoded" };
const body = {
grant_type: "authorization_code",
code,
redirect_uri: hereWithoutSearch(),
code_verifier: codeVerifier,
};
const tokenResponse = await this.makeCallJson<TokenResponse>(
"POST",
"/login/authorize/token",
{ headers, body },
);
// Persist claims. Login has succeeded.
// Perform sign-in
this.claims = claims;
this.persistClaims(claimsJSON);
persistAccessToken(tokenResponse.access_token);
this.accessToken = tokenResponse.access_token;
// Perform callback or default path replacement
// Return to indicate sign-in success
if (callback) {
if (typeof callback !== "function") {
throw new Error("Provided callback is not a function.");
}
callback({ needsKeys });
} else {
if (needsKeys) {
window.location.href = this.settingsUri(hereWithoutSearch());
} else {
window.history.replaceState(
{},
document.title,
window.location.pathname,
);
}
}
return { needsKeys: tokenResponse.needs_keys };
}
logOut(redirectUri: string): void {
this.clearClaims();
this.claims = null;
signOut(redirectUri: string): void {
this.accessToken = null;
clearPersistedData();

@@ -190,62 +148,129 @@ window.location.href = this.uri(

startLoginUri(redirectUri?: string, provider?: "google" | "slack"): string {
const params = new URLSearchParams();
params.append("redirectUri", redirectUri || window.location.href);
if (provider) {
params.append("provider", provider);
}
return this.uri(`/login/accounts?${params.toString()}`);
get stash() {
return new Stash(this);
}
// Deprecated in favor of settingsUri
getConnectLocation(redirectUri?: string): string {
return this.settingsUri(redirectUri);
get env() {
return new Environment(this);
}
// Deprecated in favor of startLoginUri
getGoogleLoginLocation(redirectUri?: string): string {
return this.startLoginUri(redirectUri, "google");
get userSetting() {
return new UserSetting(this);
}
// Deprecated
getLoginLocation(): string {
return this.uri("/login");
async loadUser(): Promise<User> {
this.assertIsSignedIn();
return await this.makeCallJson<User>("GET", "/api/v1/user");
}
getUserEmail(): string | null {
this.assertLoggedIn();
return this.claims!.email;
async run<T>(
operationId: string,
parameters: OperationParameters = {},
): Promise<OperationResponse<T>> {
const response = await this.makeCall(
"POST",
`/api/v1/execute/${operationId}`,
{ body: { parameters } },
);
const log = await extractJson<EndRequestLog>(response);
if (log.status !== "SUCCESS") {
throw new OperationError(log, response);
}
return new EndRequestLogResponse<T>(log, response);
}
getUserName(): string | null {
this.assertLoggedIn();
return this.claims!.name;
async makeCallJson<T>(
method: string,
path: string,
httpParams: HttpParams = {},
): Promise<T> {
const response = await this.makeCall(method, path, httpParams);
return extractJson<T>(response);
}
async runOperation(
operationId: string,
params: OperationParameters = {},
): Promise<EndRequestLog> {
const headers: HeadersInit = {
"Content-Type": "application/json",
};
if (this.claims) {
headers["X-PUBLIC-TOKEN"] = this.claims.publicToken;
async makeCall(
method: string,
path: string,
{ queryParams, body, headers }: HttpParams = {},
): Promise<Response> {
if (!headers) {
headers = {
"Content-Type": "application/json",
};
if (this.accessToken) {
headers.Authorization = `Bearer ${this.accessToken}`;
}
}
const response = await fetch(this.uri(`/api/v1/execute/${operationId}`), {
credentials: "include",
method: "POST",
headers,
body: JSON.stringify({
parameters: params,
}),
});
const url = new URL(path, this.hostedAppOrigin);
if (queryParams != null) {
Object.keys(queryParams).forEach(key =>
url.searchParams.append(key, queryParams[key]),
);
}
if (response.status >= 200 && response.status < 300) {
return (await response.json()) as EndRequestLog;
let bodyEncoder;
if (headers["Content-Type"] === "application/x-www-form-urlencoded") {
bodyEncoder = formUrlEncode;
} else {
throw response;
bodyEncoder = JSON.stringify;
}
const response = await trfetch(
url.href,
Object.assign(
{ method, headers },
body === null ? null : { body: bodyEncoder(body) }, // Only include body if non-null
),
);
return response;
}
}
function extractJson<T>(response: Response): Promise<T> {
return response.json().then(
x => x,
() => {
throw new APIError("Failed to read response body", response);
},
);
}
interface HttpParams {
body?: any;
headers?: { [s: string]: string };
queryParams?: { [s: string]: string };
}
export interface SignInSuccess {
needsKeys: boolean;
}
export interface OperationParameters {
[paramName: string]: string;
}
class EndRequestLogResponse<T> implements OperationResponse<T> {
results: T[];
requestId: string;
constructor(log: EndRequestLog, response: Response) {
this.requestId = log.requestId;
const logResults = log.result.results;
if (!logResults) {
throw new APIError(
"API returned an unexpected response schema",
response,
);
}
this.results = logResults;
}
get value(): T {
if (this.results.length === 0) {
throw new Error("Operation did not return a value");
}
return this.results[0];
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc