Skip to content

Commit 267e8d0

Browse files
authored
Merge pull request #52 from vemonet/fix-response-parser-to-handle-construct2
Fix the display of CONSTRUCT/DESCRIBE results in the YASR table
2 parents 6955cec + 2f476d9 commit 267e8d0

File tree

2 files changed

+47
-22
lines changed

2 files changed

+47
-22
lines changed

packages/yasqe/src/sparql.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ function getRequestConfigSettings(yasqe: Yasqe, conf?: Partial<Config["requestCo
1919
// type callback = AjaxConfig.callbacks['complete'];
2020
export function getAjaxConfig(
2121
yasqe: Yasqe,
22-
_config: Partial<Config["requestConfig"]> = {}
22+
_config: Partial<Config["requestConfig"]> = {},
2323
): PopulatedAjaxConfig | undefined {
2424
const config: RequestConfig<Yasqe> = merge(
2525
{},
2626
getRequestConfigSettings(yasqe, yasqe.config.requestConfig),
27-
getRequestConfigSettings(yasqe, _config)
27+
getRequestConfigSettings(yasqe, _config),
2828
);
2929
if (!config.endpoint || config.endpoint.length == 0) return; // nothing to query!
3030

@@ -94,18 +94,21 @@ export async function executeQuery(yasqe: Yasqe, config?: YasqeAjaxConfig): Prom
9494
const request = new Request(populatedConfig.url, fetchOptions);
9595
yasqe.emit("query", request, abortController);
9696
const response = await fetch(request);
97-
let result = await response.text();
98-
try {
99-
result = JSON.parse(result);
100-
} catch (e) {
101-
// ignore
102-
}
10397
if (!response.ok) {
104-
throw new Error(result || response.statusText);
98+
throw new Error((await response.text()) || response.statusText);
10599
}
106-
yasqe.emit("queryResponse", result, Date.now() - queryStart);
107-
yasqe.emit("queryResults", result, Date.now() - queryStart);
108-
return result;
100+
// Await the response content and merge with the `Response` object
101+
const queryResponse = {
102+
ok: response.ok,
103+
status: response.status,
104+
statusText: response.statusText,
105+
headers: response.headers,
106+
type: response.type,
107+
content: await response.text(),
108+
};
109+
yasqe.emit("queryResponse", queryResponse, Date.now() - queryStart);
110+
yasqe.emit("queryResults", queryResponse.content, Date.now() - queryStart);
111+
return queryResponse;
109112
} catch (e) {
110113
if (e instanceof Error && e.message === "Aborted") {
111114
// The query was aborted. We should not do or draw anything
@@ -153,7 +156,7 @@ export function getUrlArguments(yasqe: Yasqe, _config: Config["requestConfig"]):
153156
args.reduce((argsObject: { [key: string]: string[] }, arg) => {
154157
argsObject[arg.name] ? argsObject[arg.name].push(arg.value) : (argsObject[arg.name] = [arg.value]);
155158
return argsObject;
156-
}, {})
159+
}, {}),
157160
);
158161

159162
return data;

packages/yasr/src/parsers/index.ts

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,50 @@ const applyMustacheToLiterals: Parser.PostProcessBinding = (binding: Parser.Bind
5555
}
5656
return binding;
5757
};
58+
59+
/**
60+
* Response object from a fetch request with an additional `.content` property containing the awaited response content
61+
*/
62+
type QueryResponse = Response & {
63+
content: string;
64+
};
65+
66+
/**
67+
* Parser class for handling query responses from various formats.
68+
*
69+
* This class processes responses from SPARQL endpoints and converts them into standardized formats for further processing.
70+
* It can handle JSON, XML, CSV, TSV, and Turtle responses, detecting the format either from content-type headers
71+
* or by attempting to parse the content.
72+
*
73+
* The parser can process:
74+
* - Direct `QueryResponse` objects (regular fetch response with additional content property with the awaited response content)
75+
* - ResponseSummary objects
76+
* - Error objects
77+
* - Raw response data
78+
*
79+
* It provides methods to access parsed data in standardized formats, error information,
80+
* and utilities to convert the data for storage or export.
81+
*/
5882
class Parser {
59-
private res: Response | undefined;
83+
private res: QueryResponse | undefined;
6084
private summary: Parser.ResponseSummary | undefined;
6185
private errorSummary: Parser.ErrorSummary | undefined;
6286
private error: Error | undefined;
6387
private type: "json" | "xml" | "csv" | "tsv" | "ttl" | undefined;
6488
private executionTime: number | undefined;
65-
constructor(responseOrObject: Parser.ResponseSummary | Response | Error | any, executionTime?: number) {
89+
90+
constructor(responseOrObject: Parser.ResponseSummary | QueryResponse | Error | any, executionTime?: number) {
6691
if (responseOrObject.executionTime) this.executionTime = responseOrObject.executionTime;
6792
if (executionTime) this.executionTime = executionTime; // Parameter has priority
6893
if (responseOrObject instanceof Error) {
6994
this.error = responseOrObject;
70-
} else if ((<any>responseOrObject).xhr) {
71-
this.setResponse(<Response>responseOrObject);
95+
} else if ((<any>responseOrObject).content) {
96+
this.setResponse(<QueryResponse>responseOrObject);
7297
} else {
7398
this.setSummary(<Parser.ResponseSummary>responseOrObject);
7499
}
75100
}
76-
public setResponse(res: Response) {
101+
public setResponse(res: QueryResponse) {
77102
this.res = res;
78103
}
79104
public setSummary(summary: Parser.ResponseSummary | any) {
@@ -130,6 +155,7 @@ class Parser {
130155
}
131156
private getData(): any {
132157
if (this.res) {
158+
if (this.res.content) return this.res.content;
133159
if (this.res.body) return this.res.body;
134160
if (this.res.text) return this.res.text; //probably a construct or something
135161
}
@@ -236,10 +262,6 @@ class Parser {
236262
return data;
237263
}
238264

239-
getOriginalResponse() {
240-
return this.res?.body;
241-
}
242-
243265
getType() {
244266
if (!this.type) this.getAsJson(); //detects type as well
245267
return this.type;

0 commit comments

Comments
 (0)