Switch to using other link header parser
Signed-off-by: Robert Bunning <rbunning@webstaurantstore.com>
This commit is contained in:
@@ -39,6 +39,8 @@
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.61",
|
||||
"@types/parse-link-header": "^2.0.1",
|
||||
"parse-link-header": "^2.0.0",
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -126,7 +126,7 @@ describe('NewRelicClient', () => {
|
||||
headers: new Map<string, string | null>([
|
||||
[
|
||||
'link',
|
||||
'<https://next.page/page2?page=2>; rel="next", <https://badsite.dontgohere>; rel="next"',
|
||||
'<https://next.page/page2?page=2>; rel="next", <https://badsite.dontgohere>; rel="first"',
|
||||
],
|
||||
['otherheader', 'otherValue'],
|
||||
]),
|
||||
|
||||
@@ -20,6 +20,8 @@ import {
|
||||
FetchApi,
|
||||
} from '@backstage/core-plugin-api';
|
||||
|
||||
import parseLinkHeader from 'parse-link-header';
|
||||
|
||||
export type NewRelicApplication = {
|
||||
id: number;
|
||||
application_summary: NewRelicApplicationSummary;
|
||||
@@ -76,14 +78,8 @@ export interface NewRelicApi {
|
||||
getApplications(): Promise<NewRelicApplications>;
|
||||
}
|
||||
|
||||
interface PaginationInformation {
|
||||
nextPageLink: string;
|
||||
relation: string;
|
||||
}
|
||||
|
||||
interface NewRelicPageReadResult {
|
||||
hasMoreApplications: boolean;
|
||||
pagination: PaginationInformation | undefined;
|
||||
nextPageUrl: string | undefined;
|
||||
applicationsFromReadPage: NewRelicApplication[];
|
||||
}
|
||||
|
||||
@@ -106,20 +102,17 @@ export class NewRelicClient implements NewRelicApi {
|
||||
this.baseUrl = `${proxyUrl}${this.proxyPathBase}/apm/api/applications.json`;
|
||||
}
|
||||
|
||||
let targetUrl = this.baseUrl;
|
||||
let hasNextPage = true;
|
||||
|
||||
try {
|
||||
let applications: NewRelicApplication[] = [];
|
||||
let targetUrl = this.baseUrl;
|
||||
|
||||
do {
|
||||
const { hasMoreApplications, pagination, applicationsFromReadPage } =
|
||||
const { nextPageUrl, applicationsFromReadPage } =
|
||||
await this.fetchNewRelic(targetUrl);
|
||||
|
||||
hasNextPage = hasMoreApplications;
|
||||
targetUrl = hasNextPage ? pagination!.nextPageLink : '';
|
||||
targetUrl = nextPageUrl ?? '';
|
||||
applications = applications.concat(applicationsFromReadPage);
|
||||
} while (hasNextPage);
|
||||
} while (!!targetUrl);
|
||||
|
||||
return { applications };
|
||||
} catch (e) {
|
||||
@@ -143,37 +136,12 @@ export class NewRelicClient implements NewRelicApi {
|
||||
|
||||
const readResponse = responseJson as NewRelicApplications;
|
||||
const linkHeader = response.headers.get('link');
|
||||
const pagination = this.parseLinkHeader(linkHeader);
|
||||
const parseResult = parseLinkHeader(linkHeader);
|
||||
const nextPageNumber = parseResult?.next?.page;
|
||||
|
||||
return {
|
||||
hasMoreApplications: !!(pagination && pagination.relation === 'next'),
|
||||
pagination,
|
||||
nextPageUrl: nextPageNumber && `${this.baseUrl}?page=${nextPageNumber}`,
|
||||
applicationsFromReadPage: readResponse.applications,
|
||||
};
|
||||
}
|
||||
|
||||
private parseLinkHeader(
|
||||
linkHeader: string | null,
|
||||
): PaginationInformation | undefined {
|
||||
if (!linkHeader) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const nextRelevantLink = linkHeader.replaceAll(' ', '').split(',')[0];
|
||||
const linkParts = nextRelevantLink.match(/^<.+(\?page=.+)>;rel="(.+)"$/);
|
||||
const nextPageNumber = linkParts?.[1];
|
||||
const relation = linkParts?.[2];
|
||||
|
||||
const nextPageLink = `${this.baseUrl}${nextPageNumber}`;
|
||||
const isValidLink = !!(linkParts && nextPageNumber && relation);
|
||||
|
||||
if (!nextRelevantLink || !isValidLink) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
nextPageLink,
|
||||
relation,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7605,9 +7605,11 @@ __metadata:
|
||||
"@testing-library/react": ^12.1.3
|
||||
"@testing-library/user-event": ^14.0.0
|
||||
"@types/node": ^16.11.26
|
||||
"@types/parse-link-header": ^2.0.1
|
||||
"@types/react": ^16.13.1 || ^17.0.0
|
||||
cross-fetch: ^3.1.5
|
||||
msw: ^1.0.0
|
||||
parse-link-header: ^2.0.0
|
||||
react-use: ^17.2.4
|
||||
peerDependencies:
|
||||
react: ^16.13.1 || ^17.0.0
|
||||
@@ -17606,6 +17608,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/parse-link-header@npm:^2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "@types/parse-link-header@npm:2.0.1"
|
||||
checksum: f76678612511365aefc23704f00f3262fcb1d6bd9c4dd83f783a38e50e3ccf26615f9a62c757952cab5af6f2bd8b3b1763ce391376458afce5fe47c6fe2b80e1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/passport-auth0@npm:^1.0.5":
|
||||
version: 1.0.5
|
||||
resolution: "@types/passport-auth0@npm:1.0.5"
|
||||
@@ -34337,6 +34346,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"parse-link-header@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "parse-link-header@npm:2.0.0"
|
||||
dependencies:
|
||||
xtend: ~4.0.1
|
||||
checksum: 0e96c6af9910e8f92084b49b8dc6a10dd58db470847d1499f562576180c1ac5e49d18007697f0d538e5f3efdc8ce1d8777641f3ae225302b74af0dd0578b628e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"parse-path@npm:^7.0.0":
|
||||
version: 7.0.0
|
||||
resolution: "parse-path@npm:7.0.0"
|
||||
@@ -42745,7 +42763,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"xtend@npm:^4.0.0":
|
||||
"xtend@npm:^4.0.0, xtend@npm:~4.0.1":
|
||||
version: 4.0.2
|
||||
resolution: "xtend@npm:4.0.2"
|
||||
checksum: ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a
|
||||
|
||||
Reference in New Issue
Block a user