Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore: Release 10.0.0 #3146

Merged
merged 11 commits into from
May 8, 2024
672 changes: 521 additions & 151 deletions package-lock.json

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "graph-explorer-v2",
"version": "9.8.0",
"version": "10.0.0",
"private": true,
"dependencies": {
"@augloop/types-core": "file:packages/types-core-2.16.189.tgz",
"@axe-core/webdriverjs": "4.8.4",
"@axe-core/webdriverjs": "4.8.5",
"@azure/msal-browser": "3.10.0",
"@babel/core": "7.23.3",
"@babel/runtime": "7.23.8",
Expand All @@ -24,28 +24,28 @@
"babel-loader": "9.1.3",
"babel-preset-react-app": "10.0.1",
"bfj": "8.0.0",
"bootstrap": "5.3.2",
"bootstrap": "5.3.3",
"case-sensitive-paths-webpack-plugin": "2.4.0",
"css-loader": "6.10.0",
"dotenv": "16.4.2",
"dotenv-expand": "10.0.0",
"dotenv": "16.4.5",
"dotenv-expand": "11.0.6",
"eslint-config-react-app": "7.0.1",
"eslint-plugin-react": "7.33.2",
"eslint-webpack-plugin": "4.0.1",
"express": "4.18.2",
"express": "4.19.2",
"expvariantassignmentsdk": "file:packages/expvariantassignmentsdk-1.0.0.tgz",
"file-loader": "6.2.0",
"fork-ts-checker-webpack-plugin": "9.0.2",
"fs-extra": "11.1.1",
"fs-extra": "11.2.0",
"guid-typescript": "1.0.9",
"isomorphic-fetch": "3.0.0",
"localforage": "1.10.0",
"mini-css-extract-plugin": "2.8.0",
"mini-css-extract-plugin": "2.8.1",
"monaco-editor": "0.30.1",
"monaco-editor-webpack-plugin": "6.0.0",
"office-ui-fabric-core": "11.1.0",
"postcss-flexbugs-fixes": "5.0.2",
"postcss-loader": "7.3.3",
"postcss-loader": "8.1.1",
"postcss-preset-env": "9.3.0",
"re-resizable": "6.9.11",
"react": "18.2.0",
Expand All @@ -55,13 +55,13 @@
"redux": "4.2.1",
"redux-thunk": "2.4.2",
"resolve": "1.22.8",
"sass": "1.69.7",
"sass-loader": "13.3.2",
"style-loader": "3.3.3",
"sass": "1.72.0",
"sass-loader": "14.1.1",
"style-loader": "3.3.4",
"typescript": "5.3.3",
"url": "0.11.1",
"url": "0.11.3",
"url-loader": "4.1.1",
"webpack": "5.90.1",
"webpack": "5.90.3",
"webpack-dev-server": "4.15.1",
"webpack-manifest-plugin": "5.0.0",
"workbox-webpack-plugin": "7.0.0"
Expand Down Expand Up @@ -91,7 +91,7 @@
],
"devDependencies": {
"@axe-core/playwright": "4.7.3",
"@playwright/test": "1.40.1",
"@playwright/test": "1.42.0",
"@types/chromedriver": "81.0.1",
"@types/isomorphic-fetch": "0.0.39",
"@types/jest": "29.5.12",
Expand All @@ -106,7 +106,7 @@
"@typescript-eslint/parser": "6.17.0",
"acorn": "8.11.3",
"babel-jest": "29.7.0",
"chromedriver": "119.0.1",
"chromedriver": "122.0.4",
"eslint": "8.56.0",
"html-webpack-plugin": "5.6.0",
"jest": "29.7.0",
Expand All @@ -119,7 +119,7 @@
"react-dev-utils": "12.0.1",
"redux-logger": "3.0.6",
"redux-mock-store": "1.5.4",
"selenium-webdriver": "4.17.0",
"selenium-webdriver": "4.18.1",
"start-server-and-test": "2.0.3",
"ts-jest": "29.1.2"
},
Expand Down
11 changes: 10 additions & 1 deletion src/app/services/actions/query-action-creator-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,14 @@ export async function generateResponseDownloadUrl(
}
}

async function tryParseJson(textValue: string) {
try {
return JSON.parse(textValue);
} catch (error) {
return textValue;
}
}

export function parseResponse(
response: any,
respHeaders: any = {}
Expand All @@ -233,9 +241,10 @@ export function parseResponse(
const contentType = getContentType(response.headers);
switch (contentType) {
case ContentType.Json:
return response.json();
return response.text().then(tryParseJson);
case ContentType.XML:
case ContentType.HTML:
case ContentType.TextCsv:
case ContentType.TextPlain:
return response.text();

Expand Down
4 changes: 2 additions & 2 deletions src/app/services/actions/query-action-creators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ export function runQuery(query: IQuery) {
};

if (error instanceof ClientError) {
status.status = 0;
status.statusText = `${error.name}: ${error.message}`;
status.status = error.message;
status.statusText = error.name;
}

if (queryResultsInCorsError(query.sampleUrl)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export const ValidationProvider = ({ children }: ValidationProviderProps) => {
}, [resources])

useEffect(() => {
if (!queryVersion || !query || Object.keys(resources.data).length === 0) {
return;
}
if (version !== queryVersion && GRAPH_API_VERSIONS.includes(queryVersion)
&& resources.data[queryVersion].children!.length > 0) {
setVersionedResources(resources.data[queryVersion].children!);
Expand Down
15 changes: 8 additions & 7 deletions src/app/views/query-response/response/Response.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@

import { useDispatch } from 'react-redux';

import { AppDispatch, useAppSelector } from '../../../../store';
import { useAppSelector } from '../../../../store';
import { getContentType } from '../../../services/actions/query-action-creator-util';
import { convertVhToPx, getResponseEditorHeight,
getResponseHeight } from '../../common/dimensions/dimensions-adjustment';
import {
convertVhToPx, getResponseEditorHeight,
getResponseHeight
} from '../../common/dimensions/dimensions-adjustment';
import ResponseDisplay from './ResponseDisplay';
import { ResponseMessages } from './ResponseMessages';

const Response = () => {
const { dimensions: { response }, graphResponse, responseAreaExpanded, sampleQuery, authToken, graphExplorerMode } =
const { dimensions: { response }, graphResponse, responseAreaExpanded} =
useAppSelector((state) => state);
const { body, headers } = graphResponse;
const dispatch: AppDispatch = useDispatch();

const defaultHeight = convertVhToPx(getResponseHeight(response.height, responseAreaExpanded), 220);
const monacoHeight = getResponseEditorHeight(150);

const contentDownloadUrl = body?.contentDownloadUrl;
const throwsCorsError = body?.throwsCorsError;
const contentType = getContentType(headers);

return (
<div style={{ display: 'block' }}>
{ResponseMessages(graphResponse, sampleQuery, authToken, graphExplorerMode, dispatch)}
<ResponseMessages />
{!contentDownloadUrl && !throwsCorsError && headers &&
<ResponseDisplay
contentType={contentType}
Expand Down
78 changes: 48 additions & 30 deletions src/app/views/query-response/response/ResponseMessages.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Link, MessageBar, MessageBarType } from '@fluentui/react';
import { useState } from 'react';
import { IAuthenticateResult } from '../../../../types/authentication';
import { Mode } from '../../../../types/enums';
import { IGraphResponse } from '../../../../types/query-response';
import { useDispatch } from 'react-redux';

import { AppDispatch, useAppSelector } from '../../../../store';
import { Mode } from '../../../../types/enums';
import { IQuery } from '../../../../types/query-runner';
import { getContentType } from '../../../services/actions/query-action-creator-util';
import { runQuery } from '../../../services/actions/query-action-creators';
import { setSampleQuery } from '../../../services/actions/query-input-action-creators';
import { MOZILLA_CORS_DOCUMENTATION_LINK } from '../../../services/graph-constants';
Expand All @@ -15,31 +16,32 @@ interface ODataLink {
name: string;
}

export function ResponseMessages(
graphResponse: IGraphResponse,
sampleQuery: IQuery,
authToken: IAuthenticateResult,
graphExplorerMode: Mode,
dispatch: Function) {

function getOdataLinkFromResponseBody(responseBody: any): ODataLink | null {
const odataLinks = ['nextLink', 'deltaLink'];
let data = null;
if (responseBody) {
odataLinks.forEach(link => {
if (responseBody[`@odata.${link}`]) {
data = {
link: responseBody[`@odata.${link}`],
name: link
};
}
});
}
return data;
function getOdataLinkFromResponseBody(responseBody: any): ODataLink | null {
const odataLinks = ['nextLink', 'deltaLink'];
let data = null;
if (responseBody) {
odataLinks.forEach(link => {
if (responseBody[`@odata.${link}`]) {
data = {
link: responseBody[`@odata.${link}`],
name: link
};
}
});
}
return data;
}

export const ResponseMessages = () => {
const dispatch: AppDispatch = useDispatch();
const messageBars = [];

const { graphResponse: { body, headers }, sampleQuery, authToken, graphExplorerMode
} = useAppSelector((state) => state);
const [displayMessage, setDisplayMessage] = useState(true);

const tokenPresent = !!authToken.token;
const { body } = graphResponse;
const contentType = getContentType(headers);
const odataLink = getOdataLinkFromResponseBody(body);

const setQuery = () => {
Expand All @@ -51,7 +53,7 @@ export function ResponseMessages(

// Display link to step to next result
if (odataLink) {
return (
messageBars.push(
<MessageBar messageBarType={MessageBarType.info}>
{translateMessage('This response contains an @odata property.')}: @odata.{odataLink.name}
<Link onClick={() => setQuery()} underline>
Expand All @@ -63,7 +65,7 @@ export function ResponseMessages(

// Display link to download file response
if (body?.contentDownloadUrl) {
return (
messageBars.push(
<div>
<MessageBar messageBarType={MessageBarType.warning}>
{translateMessage('This response contains unviewable content')}
Expand All @@ -77,7 +79,7 @@ export function ResponseMessages(

// Show CORS compliance message
if (body?.throwsCorsError) {
return (
messageBars.push(
<div>
<MessageBar messageBarType={MessageBarType.warning}>
{translateMessage('Response content not available due to CORS policy')}
Expand All @@ -90,7 +92,7 @@ export function ResponseMessages(
}

if (body && !tokenPresent && displayMessage && graphExplorerMode === Mode.Complete) {
return (
messageBars.push(
<div>
<MessageBar
messageBarType={MessageBarType.warning}
Expand All @@ -104,4 +106,20 @@ export function ResponseMessages(
</div>
);
}
}

if (contentType === 'application/json' && typeof body === 'string') {
messageBars.push(
<div>
<MessageBar
messageBarType={MessageBarType.info}
onDismiss={() => setDisplayMessage(false)}
dismissButtonAriaLabel={translateMessage('Close')}
>
{translateMessage('Malformed JSON body')}
</MessageBar>
</div>
);
}

return messageBars;
}
6 changes: 3 additions & 3 deletions src/modules/authentication/AuthenticationWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ export class AuthenticationWrapper implements IAuthenticationWrapper {
}

public async logIn(sessionId = '', sampleQuery?: IQuery): Promise<AuthenticationResult> {
if(sampleQuery){
if (sampleQuery) {
this.sampleQuery = sampleQuery;
this.performingStepUpAuth = true;
}
this.consentingToNewScopes = false;
// eslint-disable-next-line no-useless-catch
try {
const authResult = await this.getAuthResult([], sessionId);
if(this.performingStepUpAuth && authResult){
if (this.performingStepUpAuth && authResult) {
this.claimsAvailable = true;
}
return authResult;
Expand Down Expand Up @@ -180,7 +180,7 @@ export class AuthenticationWrapper implements IAuthenticationWrapper {

private getClaims(): string | undefined {
const account = this.getAccount();
if(account && (this.sampleQuery.sampleUrl !== '')){
if (account && (this.sampleQuery.sampleUrl !== '')) {
const claimsChallenge = new ClaimsChallenge(this.sampleQuery, account);
const storedClaims = claimsChallenge.getClaimsFromStorage();
return storedClaims ? window.atob(storedClaims) : undefined;
Expand Down
1 change: 1 addition & 0 deletions src/types/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export enum ContentType {
TextPlain = 'text/plain',
HTML = 'text/html',
BinaryResponse = 'application/octet-stream',
TextCsv = 'text/csv',
}

export enum AppTheme {
Expand Down
Loading