mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-23 10:51:30 +00:00
Compare commits
2 Commits
replace_jq
...
esbuild
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7b5c89ff8 | ||
|
|
39f77adc11 |
47
package-lock.json
generated
47
package-lock.json
generated
@@ -9231,6 +9231,53 @@
|
||||
"through": "~2.3.6"
|
||||
}
|
||||
},
|
||||
"esbuild-loader": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.7.0.tgz",
|
||||
"integrity": "sha512-1v7PVHZ+GvHPlTYVKjNDblUZbzx58Iwt0LJrBI1INzi4/UHz9D3IJ/skNOimaypHDTohj6HtS3ExWJX2xCRzWg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esbuild": "^0.8.17",
|
||||
"loader-utils": "^2.0.0",
|
||||
"type-fest": "^0.20.2",
|
||||
"webpack-sources": "^2.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"esbuild": {
|
||||
"version": "0.8.26",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.8.26.tgz",
|
||||
"integrity": "sha512-u3MMHOOumdWoAKF+073GHPpzvVB2cM+y9VD4ZwYs1FAQ6atRPISya35dbrbOu/mM68mQ42P+nwPzQVBTfQhkvQ==",
|
||||
"dev": true
|
||||
},
|
||||
"loader-utils": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
|
||||
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
"json5": "^2.1.2"
|
||||
}
|
||||
},
|
||||
"type-fest": {
|
||||
"version": "0.20.2",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||
"dev": true
|
||||
},
|
||||
"webpack-sources": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz",
|
||||
"integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"source-list-map": "^2.0.1",
|
||||
"source-map": "^0.6.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"escalade": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
"dependencies": {
|
||||
"@azure/arm-cosmosdb": "9.1.0",
|
||||
"@azure/cosmos": "3.9.0",
|
||||
"@azure/identity": "1.1.0",
|
||||
"@azure/cosmos-language-service": "0.0.5",
|
||||
"@azure/identity": "1.1.0",
|
||||
"@jupyterlab/services": "6.0.0-rc.2",
|
||||
"@jupyterlab/terminal": "3.0.0-rc.2",
|
||||
"@microsoft/applicationinsights-web": "2.5.9",
|
||||
@@ -139,6 +139,7 @@
|
||||
"enzyme": "3.11.0",
|
||||
"enzyme-adapter-react-16": "1.15.5",
|
||||
"enzyme-to-json": "3.6.1",
|
||||
"esbuild-loader": "2.7.0",
|
||||
"eslint": "7.8.1",
|
||||
"eslint-cli": "1.1.1",
|
||||
"eslint-plugin-no-null": "1.0.2",
|
||||
|
||||
@@ -265,11 +265,9 @@ export class CassandraAPIDataClient extends TableDataClient {
|
||||
authType === AuthType.EncryptedToken
|
||||
? Constants.CassandraBackend.guestQueryApi
|
||||
: Constants.CassandraBackend.queryApi;
|
||||
const authorizationHeader = getAuthorizationHeader();
|
||||
|
||||
const response = await fetch(`${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
const data: any = await $.ajax(`${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`, {
|
||||
type: "POST",
|
||||
data: {
|
||||
accountName:
|
||||
collection && collection.container.databaseAccount && collection.container.databaseAccount().name,
|
||||
cassandraEndpoint: this.trimCassandraEndpoint(
|
||||
@@ -280,19 +278,11 @@ export class CassandraAPIDataClient extends TableDataClient {
|
||||
tableId: collection.id(),
|
||||
query,
|
||||
paginationToken
|
||||
}),
|
||||
headers: {
|
||||
[authorizationHeader.header]: authorizationHeader.token,
|
||||
[Constants.HttpHeaders.contentType]: "application/json"
|
||||
}
|
||||
},
|
||||
beforeSend: this.setAuthorizationHeader,
|
||||
error: this.handleAjaxError,
|
||||
cache: false
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
displayTokenRenewalPromptForStatus(response.status);
|
||||
throw Error(`Failed to query rows for table ${collection.id()}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
shouldNotify &&
|
||||
NotificationConsoleUtils.logConsoleInfo(
|
||||
`Successfully fetched ${data.result.length} rows for table ${collection.id()}`
|
||||
@@ -460,9 +450,9 @@ export class CassandraAPIDataClient extends TableDataClient {
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
public async getTableKeys(collection: ViewModels.Collection): Promise<CassandraTableKeys> {
|
||||
public getTableKeys(collection: ViewModels.Collection): Q.Promise<CassandraTableKeys> {
|
||||
if (!!collection.cassandraKeys) {
|
||||
return collection.cassandraKeys;
|
||||
return Q.resolve(collection.cassandraKeys);
|
||||
}
|
||||
const notificationId = NotificationConsoleUtils.logConsoleMessage(
|
||||
ConsoleDataType.InProgress,
|
||||
@@ -474,51 +464,45 @@ export class CassandraAPIDataClient extends TableDataClient {
|
||||
? Constants.CassandraBackend.guestKeysApi
|
||||
: Constants.CassandraBackend.keysApi;
|
||||
let endpoint = `${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`;
|
||||
const authorizationHeader = getAuthorizationHeader();
|
||||
|
||||
try {
|
||||
const response = await fetch(endpoint, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
accountName:
|
||||
collection && collection.container.databaseAccount && collection.container.databaseAccount().name,
|
||||
cassandraEndpoint: this.trimCassandraEndpoint(
|
||||
collection.container.databaseAccount().properties.cassandraEndpoint
|
||||
),
|
||||
resourceId: collection.container.databaseAccount().id,
|
||||
keyspaceId: collection.databaseId,
|
||||
tableId: collection.id()
|
||||
}),
|
||||
headers: {
|
||||
[authorizationHeader.header]: authorizationHeader.token,
|
||||
[Constants.HttpHeaders.contentType]: "application/json"
|
||||
const deferred = Q.defer<CassandraTableKeys>();
|
||||
$.ajax(endpoint, {
|
||||
type: "POST",
|
||||
data: {
|
||||
accountName: collection && collection.container.databaseAccount && collection.container.databaseAccount().name,
|
||||
cassandraEndpoint: this.trimCassandraEndpoint(
|
||||
collection.container.databaseAccount().properties.cassandraEndpoint
|
||||
),
|
||||
resourceId: collection.container.databaseAccount().id,
|
||||
keyspaceId: collection.databaseId,
|
||||
tableId: collection.id()
|
||||
},
|
||||
beforeSend: this.setAuthorizationHeader,
|
||||
error: this.handleAjaxError,
|
||||
cache: false
|
||||
})
|
||||
.then(
|
||||
(data: CassandraTableKeys) => {
|
||||
collection.cassandraKeys = data;
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
ConsoleDataType.Info,
|
||||
`Successfully fetched keys for table ${collection.id()}`
|
||||
);
|
||||
deferred.resolve(data);
|
||||
},
|
||||
(error: any) => {
|
||||
handleError(error, "FetchKeysCassandra", `Error fetching keys for table ${collection.id()}`);
|
||||
deferred.reject(error);
|
||||
}
|
||||
)
|
||||
.done(() => {
|
||||
NotificationConsoleUtils.clearInProgressMessageWithId(notificationId);
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
displayTokenRenewalPromptForStatus(response.status);
|
||||
throw Error(`Fetching keys for table ${collection.id()} failed`);
|
||||
}
|
||||
|
||||
const data: CassandraTableKeys = await response.json();
|
||||
collection.cassandraKeys = data;
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
ConsoleDataType.Info,
|
||||
`Successfully fetched keys for table ${collection.id()}`
|
||||
);
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
handleError(error, "FetchKeysCassandra", `Error fetching keys for table ${collection.id()}`);
|
||||
throw error;
|
||||
} finally {
|
||||
NotificationConsoleUtils.clearInProgressMessageWithId(notificationId);
|
||||
}
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
public async getTableSchema(collection: ViewModels.Collection): Promise<CassandraTableKey[]> {
|
||||
public getTableSchema(collection: ViewModels.Collection): Q.Promise<CassandraTableKey[]> {
|
||||
if (!!collection.cassandraSchema) {
|
||||
return collection.cassandraSchema;
|
||||
return Q.resolve(collection.cassandraSchema);
|
||||
}
|
||||
const notificationId = NotificationConsoleUtils.logConsoleMessage(
|
||||
ConsoleDataType.InProgress,
|
||||
@@ -530,79 +514,74 @@ export class CassandraAPIDataClient extends TableDataClient {
|
||||
? Constants.CassandraBackend.guestSchemaApi
|
||||
: Constants.CassandraBackend.schemaApi;
|
||||
let endpoint = `${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`;
|
||||
const authorizationHeader = getAuthorizationHeader();
|
||||
|
||||
try {
|
||||
const response = await fetch(endpoint, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
accountName:
|
||||
collection && collection.container.databaseAccount && collection.container.databaseAccount().name,
|
||||
cassandraEndpoint: this.trimCassandraEndpoint(
|
||||
collection.container.databaseAccount().properties.cassandraEndpoint
|
||||
),
|
||||
resourceId: collection.container.databaseAccount().id,
|
||||
keyspaceId: collection.databaseId,
|
||||
tableId: collection.id()
|
||||
}),
|
||||
headers: {
|
||||
[authorizationHeader.header]: authorizationHeader.token,
|
||||
[Constants.HttpHeaders.contentType]: "application/json"
|
||||
const deferred = Q.defer<CassandraTableKey[]>();
|
||||
$.ajax(endpoint, {
|
||||
type: "POST",
|
||||
data: {
|
||||
accountName: collection && collection.container.databaseAccount && collection.container.databaseAccount().name,
|
||||
cassandraEndpoint: this.trimCassandraEndpoint(
|
||||
collection.container.databaseAccount().properties.cassandraEndpoint
|
||||
),
|
||||
resourceId: collection.container.databaseAccount().id,
|
||||
keyspaceId: collection.databaseId,
|
||||
tableId: collection.id()
|
||||
},
|
||||
beforeSend: this.setAuthorizationHeader,
|
||||
error: this.handleAjaxError,
|
||||
cache: false
|
||||
})
|
||||
.then(
|
||||
(data: any) => {
|
||||
collection.cassandraSchema = data.columns;
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
ConsoleDataType.Info,
|
||||
`Successfully fetched schema for table ${collection.id()}`
|
||||
);
|
||||
deferred.resolve(data.columns);
|
||||
},
|
||||
(error: any) => {
|
||||
handleError(error, "FetchSchemaCassandra", `Error fetching schema for table ${collection.id()}`);
|
||||
deferred.reject(error);
|
||||
}
|
||||
)
|
||||
.done(() => {
|
||||
NotificationConsoleUtils.clearInProgressMessageWithId(notificationId);
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
displayTokenRenewalPromptForStatus(response.status);
|
||||
throw Error(`Failed to fetch schema for table ${collection.id()}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
collection.cassandraSchema = data.columns;
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
ConsoleDataType.Info,
|
||||
`Successfully fetched schema for table ${collection.id()}`
|
||||
);
|
||||
|
||||
return data.columns;
|
||||
} catch (error) {
|
||||
handleError(error, "FetchSchemaCassandra", `Error fetching schema for table ${collection.id()}`);
|
||||
throw error;
|
||||
} finally {
|
||||
NotificationConsoleUtils.clearInProgressMessageWithId(notificationId);
|
||||
}
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
private async createOrDeleteQuery(
|
||||
private createOrDeleteQuery(
|
||||
cassandraEndpoint: string,
|
||||
resourceId: string,
|
||||
query: string,
|
||||
explorer: Explorer
|
||||
): Promise<void> {
|
||||
): Q.Promise<any> {
|
||||
const deferred = Q.defer();
|
||||
const authType = window.authType;
|
||||
const apiEndpoint: string =
|
||||
authType === AuthType.EncryptedToken
|
||||
? Constants.CassandraBackend.guestCreateOrDeleteApi
|
||||
: Constants.CassandraBackend.createOrDeleteApi;
|
||||
const authorizationHeader = getAuthorizationHeader();
|
||||
|
||||
const response = await fetch(`${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
$.ajax(`${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`, {
|
||||
type: "POST",
|
||||
data: {
|
||||
accountName: explorer.databaseAccount() && explorer.databaseAccount().name,
|
||||
cassandraEndpoint: this.trimCassandraEndpoint(cassandraEndpoint),
|
||||
resourceId,
|
||||
query
|
||||
}),
|
||||
headers: {
|
||||
[authorizationHeader.header]: authorizationHeader.token,
|
||||
[Constants.HttpHeaders.contentType]: "application/json"
|
||||
resourceId: resourceId,
|
||||
query: query
|
||||
},
|
||||
beforeSend: this.setAuthorizationHeader,
|
||||
error: this.handleAjaxError,
|
||||
cache: false
|
||||
}).then(
|
||||
(data: any) => {
|
||||
deferred.resolve();
|
||||
},
|
||||
reason => {
|
||||
deferred.reject(reason);
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
displayTokenRenewalPromptForStatus(response.status);
|
||||
throw Error(`Failed to create or delete keyspace/table`);
|
||||
}
|
||||
);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
private trimCassandraEndpoint(cassandraEndpoint: string): string {
|
||||
@@ -621,6 +600,13 @@ export class CassandraAPIDataClient extends TableDataClient {
|
||||
return cassandraEndpoint;
|
||||
}
|
||||
|
||||
private setAuthorizationHeader: (xhr: XMLHttpRequest) => boolean = (xhr: XMLHttpRequest): boolean => {
|
||||
const authorizationHeaderMetadata: ViewModels.AuthorizationTokenHeaderMetadata = getAuthorizationHeader();
|
||||
xhr.setRequestHeader(authorizationHeaderMetadata.header, authorizationHeaderMetadata.token);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
private isStringType(dataType: string): boolean {
|
||||
// TODO figure out rest of types that are considered strings by Cassandra (if any have been missed)
|
||||
return (
|
||||
@@ -634,4 +620,12 @@ export class CassandraAPIDataClient extends TableDataClient {
|
||||
private getCassandraPartitionKeyProperty(collection: ViewModels.Collection): string {
|
||||
return collection.cassandraKeys.partitionKeys[0].property;
|
||||
}
|
||||
|
||||
private handleAjaxError = (xhrObj: XMLHttpRequest, textStatus: string, errorThrown: string): void => {
|
||||
if (!xhrObj) {
|
||||
return;
|
||||
}
|
||||
|
||||
displayTokenRenewalPromptForStatus(xhrObj.status);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility"
|
||||
import * as Logger from "../../Common/Logger";
|
||||
import { configContext } from "../../ConfigContext";
|
||||
import { userContext } from "../../UserContext";
|
||||
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
|
||||
|
||||
export default class AuthHeadersUtil {
|
||||
public static serverId: string = Constants.ServerIds.productionPortal;
|
||||
@@ -38,7 +37,8 @@ export default class AuthHeadersUtil {
|
||||
cacheLocation: window.navigator.userAgent.indexOf("Edge") > -1 ? "localStorage" : undefined
|
||||
});
|
||||
|
||||
public static async getAccessInputMetadata(accessInput: string): Promise<DataModels.AccessInputMetadata> {
|
||||
public static getAccessInputMetadata(accessInput: string): Q.Promise<DataModels.AccessInputMetadata> {
|
||||
const deferred: Q.Deferred<DataModels.AccessInputMetadata> = Q.defer<DataModels.AccessInputMetadata>();
|
||||
const url = `${configContext.BACKEND_ENDPOINT}${Constants.ApiEndpoints.guestRuntimeProxy}/accessinputmetadata`;
|
||||
const authType: string = (<any>window).authType;
|
||||
const headers: { [headerName: string]: string } = {};
|
||||
@@ -49,55 +49,58 @@ export default class AuthHeadersUtil {
|
||||
headers[Constants.HttpHeaders.connectionString] = accessInput;
|
||||
}
|
||||
|
||||
let responseText: string;
|
||||
try {
|
||||
const timeout = setTimeout(() => {
|
||||
throw Error("Request timed out while fetching access input metadata");
|
||||
}, Constants.ClientDefaults.requestTimeoutMs);
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: "GET",
|
||||
headers: headers,
|
||||
cache: false,
|
||||
dataType: "text"
|
||||
}).then(
|
||||
(data: string, textStatus: string, xhr: JQueryXHR<any>) => {
|
||||
if (!data) {
|
||||
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, `Failed to get access input metadata`);
|
||||
deferred.reject(`Failed to get access input metadata`);
|
||||
}
|
||||
|
||||
const response = await fetch(url, {
|
||||
headers,
|
||||
method: "GET"
|
||||
});
|
||||
|
||||
clearTimeout(timeout);
|
||||
|
||||
responseText = await response.text();
|
||||
if (!response.ok || !responseText) {
|
||||
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, `Failed to get access input metadata`);
|
||||
throw Error("Failed to get access input metadata");
|
||||
try {
|
||||
const metadata: DataModels.AccessInputMetadata = JSON.parse(JSON.parse(data));
|
||||
deferred.resolve(metadata); // TODO: update to a single JSON parse once backend response is stringified exactly once
|
||||
} catch (error) {
|
||||
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, "Failed to parse access input metadata");
|
||||
deferred.reject("Failed to parse access input metadata");
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
(xhr: JQueryXHR<any>, textStatus: string, error: any) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
ConsoleDataType.Error,
|
||||
`Error while fetching access input metadata: ${JSON.stringify(xhr.responseText)}`
|
||||
);
|
||||
deferred.reject(xhr.responseText);
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage: string = getErrorMessage(error);
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
ConsoleDataType.Error,
|
||||
`Error while fetching access input metadata: ${errorMessage}`
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
);
|
||||
|
||||
try {
|
||||
const metadata: DataModels.AccessInputMetadata = JSON.parse(JSON.parse(responseText));
|
||||
return metadata; // TODO: update to a single JSON parse once backend response is stringified exactly once
|
||||
} catch (error) {
|
||||
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, "Failed to parse access input metadata");
|
||||
throw error;
|
||||
}
|
||||
return deferred.promise.timeout(Constants.ClientDefaults.requestTimeoutMs);
|
||||
}
|
||||
|
||||
public static async generateEncryptedToken(): Promise<DataModels.GenerateTokenResponse> {
|
||||
public static generateEncryptedToken(): Q.Promise<DataModels.GenerateTokenResponse> {
|
||||
const url = configContext.BACKEND_ENDPOINT + "/api/tokens/generateToken" + AuthHeadersUtil._generateResourceUrl();
|
||||
const explorer = window.dataExplorer;
|
||||
const headers: any = { authorization: userContext.authorizationToken };
|
||||
headers[Constants.HttpHeaders.getReadOnlyKey] = !explorer.hasWriteAccess();
|
||||
headers[Constants.HttpHeaders.contentType] = "application/json";
|
||||
|
||||
return await AuthHeadersUtil._initiateGenerateTokenRequest(url, "POST", headers);
|
||||
return AuthHeadersUtil._initiateGenerateTokenRequest({
|
||||
url: url,
|
||||
type: "POST",
|
||||
headers: headers,
|
||||
contentType: "application/json",
|
||||
cache: false
|
||||
});
|
||||
}
|
||||
|
||||
public static async generateUnauthenticatedEncryptedTokenForConnectionString(
|
||||
public static generateUnauthenticatedEncryptedTokenForConnectionString(
|
||||
connectionString: string
|
||||
): Promise<DataModels.GenerateTokenResponse> {
|
||||
): Q.Promise<DataModels.GenerateTokenResponse> {
|
||||
if (!connectionString) {
|
||||
return Q.reject("None or empty connection string specified");
|
||||
}
|
||||
@@ -105,9 +108,14 @@ export default class AuthHeadersUtil {
|
||||
const url = configContext.BACKEND_ENDPOINT + "/api/guest/tokens/generateToken";
|
||||
const headers: any = {};
|
||||
headers[Constants.HttpHeaders.connectionString] = connectionString;
|
||||
headers[Constants.HttpHeaders.contentType] = "application/json";
|
||||
|
||||
return await AuthHeadersUtil._initiateGenerateTokenRequest(url, "POST", headers);
|
||||
return AuthHeadersUtil._initiateGenerateTokenRequest({
|
||||
url: url,
|
||||
type: "POST",
|
||||
headers: headers,
|
||||
contentType: "application/json",
|
||||
cache: false
|
||||
});
|
||||
}
|
||||
|
||||
public static isUserSignedIn(): boolean {
|
||||
@@ -274,27 +282,24 @@ export default class AuthHeadersUtil {
|
||||
return `?resourceUrl=${resourceUrl}&rid=${rid}&rtype=${rtype}&sid=${sid}&rg=${rg}&dba=${dba}&api=${apiKind}`;
|
||||
}
|
||||
|
||||
private static async _initiateGenerateTokenRequest(
|
||||
url: string,
|
||||
method: string,
|
||||
headers: any
|
||||
): Promise<DataModels.GenerateTokenResponse> {
|
||||
const timeout = setTimeout(() => {
|
||||
throw Error("Request timed out while generating token");
|
||||
}, Constants.ClientDefaults.requestTimeoutMs);
|
||||
private static _initiateGenerateTokenRequest(
|
||||
requestSettings: JQueryAjaxSettings<any>
|
||||
): Q.Promise<DataModels.GenerateTokenResponse> {
|
||||
const deferred: Q.Deferred<DataModels.GenerateTokenResponse> = Q.defer<DataModels.GenerateTokenResponse>();
|
||||
|
||||
const response = await fetch(url, {
|
||||
headers,
|
||||
method
|
||||
});
|
||||
$.ajax(requestSettings).then(
|
||||
(data: string, textStatus: string, xhr: JQueryXHR<any>) => {
|
||||
if (!data) {
|
||||
deferred.reject("No token generated");
|
||||
}
|
||||
|
||||
clearTimeout(timeout);
|
||||
deferred.resolve(JSON.parse(data));
|
||||
},
|
||||
(xhr: JQueryXHR<any>, textStatus: string, error: any) => {
|
||||
deferred.reject(xhr.responseText);
|
||||
}
|
||||
);
|
||||
|
||||
const token: string = await response.json();
|
||||
if (response.ok && token) {
|
||||
return JSON.parse(token);
|
||||
}
|
||||
|
||||
throw Error("No token generated");
|
||||
return deferred.promise.timeout(Constants.ClientDefaults.requestTimeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"downlevelIteration": true,
|
||||
"module": "esnext",
|
||||
"target": "es5",
|
||||
"target": "es2017",
|
||||
"lib": ["es5", "es6", "dom", "webworker.importscripts"],
|
||||
"jsx": "react",
|
||||
"moduleResolution": "node",
|
||||
|
||||
@@ -9,8 +9,8 @@ const CaseSensitivePathsPlugin = require("case-sensitive-paths-webpack-plugin");
|
||||
const CreateFileWebpack = require("create-file-webpack");
|
||||
const childProcess = require("child_process");
|
||||
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const isCI = require("is-ci");
|
||||
const { ESBuildPlugin, ESBuildMinifyPlugin } = require("esbuild-loader");
|
||||
|
||||
const gitSha = childProcess.execSync("git rev-parse HEAD").toString("utf8");
|
||||
|
||||
@@ -56,37 +56,20 @@ const htmlRule = {
|
||||
]
|
||||
};
|
||||
|
||||
// We compile our own code with ts-loader
|
||||
const typescriptRule = {
|
||||
test: /\.tsx?$/,
|
||||
use: [
|
||||
{
|
||||
loader: "ts-loader",
|
||||
loader: "esbuild-loader",
|
||||
options: {
|
||||
transpileOnly: true
|
||||
loader: "tsx",
|
||||
target: "es2017"
|
||||
}
|
||||
}
|
||||
],
|
||||
exclude: /node_modules/
|
||||
};
|
||||
|
||||
// Third party modules are compiled with babel since using ts-loader that much causes webpack to run out of memory
|
||||
const ModulesRule = {
|
||||
test: /\.js$/,
|
||||
use: [
|
||||
{
|
||||
loader: "babel-loader",
|
||||
options: {
|
||||
cacheDirectory: ".cache/babel",
|
||||
presets: [["@babel/preset-env", { targets: { ie: "11" }, useBuiltIns: false }]]
|
||||
}
|
||||
}
|
||||
],
|
||||
include: /node_modules/,
|
||||
// Exclude large modules we know don't need transpiling
|
||||
exclude: /vega|monaco|plotly/
|
||||
};
|
||||
|
||||
module.exports = function(env = {}, argv = {}) {
|
||||
const mode = argv.mode || "development";
|
||||
const rules = [fontRule, lessRule, imagesRule, cssRule, htmlRule, typescriptRule];
|
||||
@@ -96,7 +79,6 @@ module.exports = function(env = {}, argv = {}) {
|
||||
};
|
||||
|
||||
if (mode === "production") {
|
||||
rules.push(ModulesRule);
|
||||
envVars.NODE_ENV = "production";
|
||||
}
|
||||
|
||||
@@ -105,6 +87,7 @@ module.exports = function(env = {}, argv = {}) {
|
||||
}
|
||||
|
||||
const plugins = [
|
||||
new ESBuildPlugin(),
|
||||
new CleanWebpackPlugin(["dist"]),
|
||||
new CreateFileWebpack({
|
||||
path: "./dist",
|
||||
@@ -211,13 +194,8 @@ module.exports = function(env = {}, argv = {}) {
|
||||
optimization: {
|
||||
minimize: mode === "production" ? true : false,
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
cache: ".cache/terser",
|
||||
terserOptions: {
|
||||
// These options increase our initial bundle size by ~5% but the builds are significantly faster and won't run out of memory
|
||||
compress: false,
|
||||
mangle: true
|
||||
}
|
||||
new ESBuildMinifyPlugin({
|
||||
target: "es2017" // Syntax to compile to (see options below for possible values)
|
||||
})
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user