mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
fix: Add content-negotiation when fetching dataset from url
* Solution works but tests don't * refactor(FetchUtil): use arrayifyStream * refactor(FetchUtil): split fetchDataset into 2 separate functions * style(FetchUtil): onelining instead of declaring new local var * test: trying to mock rdfDereferencer * refactor: promise can't have async function as arg * test(FetchUtil): pass Quad array to mockDereference instead * test: all tests should pass now and coverage is back to 100% * style: comment typo * chore: make package.json and package-lock.json compatible with main * chore: fix package.json double entries * chore: updated package.json to be alfabetical again * refactor(AgentGroupAccessChecker): Remove converter from contructor and config * refactor(TokenOwnerShipValidator): Remove converter from constructor and config * refactor(FetchUtil): Return BadRequestHttpError instead of generic Error * test(FetchUtil): return Response object instead of mocking fetch * style: typos and newlines
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import type { Readable } from 'stream';
|
||||
import type { Quad } from '@rdfjs/types';
|
||||
import arrayifyStream from 'arrayify-stream';
|
||||
import type { Response } from 'cross-fetch';
|
||||
import { fetch } from 'cross-fetch';
|
||||
import rdfDereferencer from 'rdf-dereference';
|
||||
import { BasicRepresentation } from '../http/representation/BasicRepresentation';
|
||||
import type { Representation } from '../http/representation/Representation';
|
||||
import { getLoggerFor } from '../logging/LogUtil';
|
||||
@@ -12,24 +15,32 @@ const logger = getLoggerFor('FetchUtil');
|
||||
|
||||
/**
|
||||
* Fetches an RDF dataset from the given URL.
|
||||
* Input can also be a Response if the request was already made.
|
||||
*
|
||||
* Response will be a Representation with content-type internal/quads.
|
||||
*/
|
||||
export async function fetchDataset(url: string): Promise<Representation> {
|
||||
// Try content negotiation to parse quads from the URL
|
||||
return (async(): Promise<Representation> => {
|
||||
try {
|
||||
const quadStream = (await rdfDereferencer.dereference(url)).quads as Readable;
|
||||
const quadArray = await arrayifyStream(quadStream) as Quad[];
|
||||
return new BasicRepresentation(quadArray, { path: url }, INTERNAL_QUADS, false);
|
||||
} catch {
|
||||
throw new BadRequestHttpError(`Could not parse resource at URL (${url})!`);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a given Response (from a request that was already made) to an RDF dataset.
|
||||
* In case the given Response object was already parsed its body can be passed along as a string.
|
||||
*
|
||||
* The converter will be used to convert the response body to RDF.
|
||||
*
|
||||
* Response will be a Representation with content-type internal/quads.
|
||||
*/
|
||||
export async function fetchDataset(url: string, converter: RepresentationConverter): Promise<Representation>;
|
||||
export async function fetchDataset(response: Response, converter: RepresentationConverter, body?: string):
|
||||
Promise<Representation>;
|
||||
export async function fetchDataset(input: string | Response, converter: RepresentationConverter, body?: string):
|
||||
export async function responseToDataset(response: Response, converter: RepresentationConverter, body?: string):
|
||||
Promise<Representation> {
|
||||
let response: Response;
|
||||
if (typeof input === 'string') {
|
||||
response = await fetch(input);
|
||||
} else {
|
||||
response = input;
|
||||
}
|
||||
if (!body) {
|
||||
body = await response.text();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user