mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Use baseIRI in QuadToRdfConverter.
Closes https://github.com/solid/community-server/issues/512
This commit is contained in:
parent
cabdf7960f
commit
4638ba4bce
6
package-lock.json
generated
6
package-lock.json
generated
@ -7136,9 +7136,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"n3": {
|
"n3": {
|
||||||
"version": "1.7.0",
|
"version": "1.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/n3/-/n3-1.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/n3/-/n3-1.8.0.tgz",
|
||||||
"integrity": "sha512-8R0Qj545WnVLQxOfxxyFKzOpO13hF3jhSMJfO0FNqvbsPZDiR9ZDmGGjXAlcoZDf/88OsCYd7rHML284vm1h6A==",
|
"integrity": "sha512-/PEmoB3UJrG6aXGZenDHFBJtmPp2rtfB2YLzAm2dU9stInD+ztvy4fKv5fv2ggsrSlpu7BYDTsz/c6S391uuEg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"queue-microtask": "^1.1.2",
|
"queue-microtask": "^1.1.2",
|
||||||
"readable-stream": "^3.6.0"
|
"readable-stream": "^3.6.0"
|
||||||
|
@ -96,7 +96,7 @@
|
|||||||
"fetch-sparql-endpoint": "^1.8.0",
|
"fetch-sparql-endpoint": "^1.8.0",
|
||||||
"handlebars": "^4.7.6",
|
"handlebars": "^4.7.6",
|
||||||
"mime-types": "^2.1.27",
|
"mime-types": "^2.1.27",
|
||||||
"n3": "^1.7.0",
|
"n3": "^1.8.0",
|
||||||
"rdf-parse": "^1.5.0",
|
"rdf-parse": "^1.5.0",
|
||||||
"rdf-serialize": "^1.0.0",
|
"rdf-serialize": "^1.0.0",
|
||||||
"rdf-terms": "^1.5.1",
|
"rdf-terms": "^1.5.1",
|
||||||
|
@ -24,7 +24,8 @@ export class QuadToRdfConverter extends TypedRepresentationConverter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async handle({ representation: quads, preferences }: RepresentationConverterArgs): Promise<Representation> {
|
public async handle({ identifier, representation: quads, preferences }: RepresentationConverterArgs):
|
||||||
|
Promise<Representation> {
|
||||||
const contentType = matchingMediaTypes(preferences.type, await this.getOutputTypes())[0];
|
const contentType = matchingMediaTypes(preferences.type, await this.getOutputTypes())[0];
|
||||||
let data: Readable;
|
let data: Readable;
|
||||||
|
|
||||||
@ -32,7 +33,8 @@ export class QuadToRdfConverter extends TypedRepresentationConverter {
|
|||||||
if (/(?:turtle|trig)$/u.test(contentType)) {
|
if (/(?:turtle|trig)$/u.test(contentType)) {
|
||||||
const prefixes = Object.fromEntries(quads.metadata.quads(null, PREFERRED_PREFIX_TERM, null)
|
const prefixes = Object.fromEntries(quads.metadata.quads(null, PREFERRED_PREFIX_TERM, null)
|
||||||
.map(({ subject, object }): [string, string] => [ object.value, subject.value ]));
|
.map(({ subject, object }): [string, string] => [ object.value, subject.value ]));
|
||||||
data = pipeSafely(quads.data, new StreamWriter({ format: contentType, prefixes }));
|
const options = { format: contentType, baseIRI: identifier.path, prefixes };
|
||||||
|
data = pipeSafely(quads.data, new StreamWriter(options));
|
||||||
// Otherwise, write without prefixes
|
// Otherwise, write without prefixes
|
||||||
} else {
|
} else {
|
||||||
data = rdfSerializer.serialize(quads.data, { contentType }) as Readable;
|
data = rdfSerializer.serialize(quads.data, { contentType }) as Readable;
|
||||||
|
@ -64,7 +64,7 @@ describe.each(stores)('An LDP handler without auth using %s', (name, { storeUrn,
|
|||||||
expect(response.getHeaders()).toHaveProperty('content-type', 'text/turtle');
|
expect(response.getHeaders()).toHaveProperty('content-type', 'text/turtle');
|
||||||
|
|
||||||
const data = response._getData().toString();
|
const data = response._getData().toString();
|
||||||
expect(data).toContain(`<${BASE}/> a ldp:Container`);
|
expect(data).toContain(`<> a ldp:Container`);
|
||||||
expect(response.getHeaders().link).toContain(`<${LDP.Container}>; rel="type"`);
|
expect(response.getHeaders().link).toContain(`<${LDP.Container}>; rel="type"`);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ describe.each(stores)('An LDP handler without auth using %s', (name, { storeUrn,
|
|||||||
response = await resourceHelper.performRequest(new URL(`${BASE}/${slug}/`), 'GET', { accept: 'text/turtle' });
|
response = await resourceHelper.performRequest(new URL(`${BASE}/${slug}/`), 'GET', { accept: 'text/turtle' });
|
||||||
expect(response.statusCode).toBe(200);
|
expect(response.statusCode).toBe(200);
|
||||||
|
|
||||||
const parser = new Parser();
|
const parser = new Parser({ baseIRI: `${BASE}/${slug}/` });
|
||||||
const quads = parser.parse(response._getData());
|
const quads = parser.parse(response._getData());
|
||||||
expect(quads.some((entry): boolean => entry.equals(quad(
|
expect(quads.some((entry): boolean => entry.equals(quad(
|
||||||
namedNode(`${BASE}/${slug}/`),
|
namedNode(`${BASE}/${slug}/`),
|
||||||
|
@ -12,11 +12,11 @@ import { DC, PREFERRED_PREFIX_TERM } from '../../../../src/util/Vocabularies';
|
|||||||
|
|
||||||
describe('A QuadToRdfConverter', (): void => {
|
describe('A QuadToRdfConverter', (): void => {
|
||||||
const converter = new QuadToRdfConverter();
|
const converter = new QuadToRdfConverter();
|
||||||
const identifier: ResourceIdentifier = { path: 'path' };
|
const identifier: ResourceIdentifier = { path: 'http://example.org/foo/bar/' };
|
||||||
let metadata: RepresentationMetadata;
|
let metadata: RepresentationMetadata;
|
||||||
|
|
||||||
beforeEach((): void => {
|
beforeEach((): void => {
|
||||||
metadata = new RepresentationMetadata(INTERNAL_QUADS);
|
metadata = new RepresentationMetadata(identifier, INTERNAL_QUADS);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports parsing quads.', async(): Promise<void> => {
|
it('supports parsing quads.', async(): Promise<void> => {
|
||||||
@ -35,7 +35,7 @@ describe('A QuadToRdfConverter', (): void => {
|
|||||||
.resolves.toEqual(outputPreferences);
|
.resolves.toEqual(outputPreferences);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can handle quad to turtle conversions.', async(): Promise<void> => {
|
it('can handle quad to Turtle conversions.', async(): Promise<void> => {
|
||||||
const representation = { metadata } as Representation;
|
const representation = { metadata } as Representation;
|
||||||
const preferences: RepresentationPreferences = { type: { 'text/turtle': 1 }};
|
const preferences: RepresentationPreferences = { type: { 'text/turtle': 1 }};
|
||||||
await expect(converter.canHandle({ identifier, representation, preferences })).resolves.toBeUndefined();
|
await expect(converter.canHandle({ identifier, representation, preferences })).resolves.toBeUndefined();
|
||||||
@ -47,7 +47,7 @@ describe('A QuadToRdfConverter', (): void => {
|
|||||||
await expect(converter.canHandle({ identifier, representation, preferences })).resolves.toBeUndefined();
|
await expect(converter.canHandle({ identifier, representation, preferences })).resolves.toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('converts quads to turtle.', async(): Promise<void> => {
|
it('converts quads to Turtle.', async(): Promise<void> => {
|
||||||
const representation = {
|
const representation = {
|
||||||
data: streamifyArray([ triple(
|
data: streamifyArray([ triple(
|
||||||
namedNode('http://test.com/s'),
|
namedNode('http://test.com/s'),
|
||||||
@ -69,7 +69,7 @@ describe('A QuadToRdfConverter', (): void => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('converts quads with prefixes to turtle.', async(): Promise<void> => {
|
it('converts quads with prefixes to Turtle.', async(): Promise<void> => {
|
||||||
metadata.addQuad(DC.terms.namespace, PREFERRED_PREFIX_TERM, 'dc');
|
metadata.addQuad(DC.terms.namespace, PREFERRED_PREFIX_TERM, 'dc');
|
||||||
metadata.addQuad('http://test.com/', PREFERRED_PREFIX_TERM, 'test');
|
metadata.addQuad('http://test.com/', PREFERRED_PREFIX_TERM, 'test');
|
||||||
const representation = {
|
const representation = {
|
||||||
@ -82,10 +82,6 @@ describe('A QuadToRdfConverter', (): void => {
|
|||||||
} as Representation;
|
} as Representation;
|
||||||
const preferences: RepresentationPreferences = { type: { 'text/turtle': 1 }};
|
const preferences: RepresentationPreferences = { type: { 'text/turtle': 1 }};
|
||||||
const result = await converter.handle({ identifier, representation, preferences });
|
const result = await converter.handle({ identifier, representation, preferences });
|
||||||
expect(result).toMatchObject({
|
|
||||||
binary: true,
|
|
||||||
metadata: expect.any(RepresentationMetadata),
|
|
||||||
});
|
|
||||||
expect(result.metadata.contentType).toEqual('text/turtle');
|
expect(result.metadata.contentType).toEqual('text/turtle');
|
||||||
await expect(stringifyStream(result.data)).resolves.toEqual(
|
await expect(stringifyStream(result.data)).resolves.toEqual(
|
||||||
`@prefix dc: <http://purl.org/dc/terms/>.
|
`@prefix dc: <http://purl.org/dc/terms/>.
|
||||||
@ -96,6 +92,24 @@ test:s dc:modified test:o.
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('uses the base IRI when converting quads to Turtle.', async(): Promise<void> => {
|
||||||
|
const representation = {
|
||||||
|
data: streamifyArray([ triple(
|
||||||
|
namedNode('http://example.org/foo/bar/'),
|
||||||
|
namedNode('http://example.org/foo/bar/#abc'),
|
||||||
|
namedNode('http://example.org/foo/bar/def/ghi'),
|
||||||
|
) ]),
|
||||||
|
metadata,
|
||||||
|
} as Representation;
|
||||||
|
const preferences: RepresentationPreferences = { type: { 'text/turtle': 1 }};
|
||||||
|
const result = await converter.handle({ identifier, representation, preferences });
|
||||||
|
expect(result.metadata.contentType).toEqual('text/turtle');
|
||||||
|
await expect(stringifyStream(result.data)).resolves.toEqual(
|
||||||
|
`<> <#abc> <def/ghi>.
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('converts quads to JSON-LD.', async(): Promise<void> => {
|
it('converts quads to JSON-LD.', async(): Promise<void> => {
|
||||||
metadata.contentType = INTERNAL_QUADS;
|
metadata.contentType = INTERNAL_QUADS;
|
||||||
const representation = {
|
const representation = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user