-
Notifications
You must be signed in to change notification settings - Fork 121
/
SparqlUpdateBodyParser.ts
59 lines (54 loc) · 2.36 KB
/
SparqlUpdateBodyParser.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import { PassThrough } from 'stream';
import type { Algebra } from 'sparqlalgebrajs';
import { translate } from 'sparqlalgebrajs';
import type { HttpRequest } from '../../server/HttpRequest';
import { APPLICATION_SPARQL_UPDATE } from '../../util/ContentTypes';
import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError';
import { UnsupportedMediaTypeHttpError } from '../../util/errors/UnsupportedMediaTypeHttpError';
import { pipeStreamsAndErrors, readableToString } from '../../util/Util';
import { BodyParser } from './BodyParser';
import type { MetadataHandler } from './metadata/MetadataHandler';
import type { SparqlUpdatePatch } from './SparqlUpdatePatch';
/**
* {@link BodyParser} that supports `application/sparql-update` content.
* Will convert the incoming update string to algebra in a {@link SparqlUpdatePatch}.
* Still needs access to a handler for parsing metadata.
*/
export class SparqlUpdateBodyParser extends BodyParser {
private readonly metadataHandler: MetadataHandler;
public constructor(metadataHandler: MetadataHandler) {
super();
this.metadataHandler = metadataHandler;
}
public async canHandle(input: HttpRequest): Promise<void> {
if (input.headers['content-type'] !== APPLICATION_SPARQL_UPDATE) {
throw new UnsupportedMediaTypeHttpError('This parser only supports SPARQL UPDATE data.');
}
}
public async handle(input: HttpRequest): Promise<SparqlUpdatePatch> {
// Note that readableObjectMode is only defined starting from Node 12
// It is impossible to check if object mode is enabled in Node 10 (without accessing private variables)
const options = { objectMode: input.readableObjectMode };
const toAlgebraStream = new PassThrough(options);
const dataCopy = new PassThrough(options);
pipeStreamsAndErrors(input, toAlgebraStream);
pipeStreamsAndErrors(input, dataCopy);
let algebra: Algebra.Operation;
try {
const sparql = await readableToString(toAlgebraStream);
algebra = translate(sparql, { quads: true });
} catch (error: unknown) {
if (error instanceof Error) {
throw new UnsupportedHttpError(error.message);
}
throw new UnsupportedHttpError();
}
// Prevent body from being requested again
return {
algebra,
binary: true,
data: dataCopy,
metadata: await this.metadataHandler.handleSafe(input),
};
}
}