Skip to content

Commit

Permalink
Merge 4dde70f into e88e680
Browse files Browse the repository at this point in the history
  • Loading branch information
freyavs committed Aug 31, 2020
2 parents e88e680 + 4dde70f commit 2646c88
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 11 deletions.
3 changes: 1 addition & 2 deletions src/storage/FileResourceStore.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { createReadStream, createWriteStream, promises as fsPromises, Stats } from 'fs';
import { posix } from 'path';
import { Readable } from 'stream';
import arrayifyStream from 'arrayify-stream';
import { contentType as getContentTypeFromExtension } from 'mime-types';
import { Quad } from 'rdf-js';
import streamifyArray from 'streamify-array';
Expand Down Expand Up @@ -289,7 +288,7 @@ export class FileResourceStore implements ResourceStore {
let rawMetadata: Quad[] = [];
try {
const readMetadataStream = createReadStream(joinPath(path, '.metadata'));
rawMetadata = await arrayifyStream(readMetadataStream);
rawMetadata = await this.metadataController.generateQuadsFromReadable(readMetadataStream);
} catch (_) {
// Metadata file doesn't exist so lets keep `rawMetaData` an empty array.
}
Expand Down
6 changes: 2 additions & 4 deletions src/storage/conversion/RdfToQuadConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import rdfParser from 'rdf-parse';
import { Representation } from '../../ldp/representation/Representation';
import { RepresentationMetadata } from '../../ldp/representation/RepresentationMetadata';
import { CONTENT_TYPE_QUADS, DATA_TYPE_QUAD } from '../../util/ContentTypes';
import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError';
import { pipeStreams } from '../../util/Util';
import { checkRequest } from './ConversionUtil';
import { RepresentationConverter, RepresentationConverterArgs } from './RepresentationConverter';

Expand All @@ -29,12 +29,10 @@ export class RdfToQuadConverter extends RepresentationConverter {
contentType: representation.metadata.contentType as string,
baseIRI,
});
data.pipe(errorStream);
data.on('error', (error): boolean => errorStream.emit('error', new UnsupportedHttpError(error.message)));

return {
dataType: DATA_TYPE_QUAD,
data: errorStream,
data: pipeStreams(data, errorStream),
metadata,
};
}
Expand Down
5 changes: 3 additions & 2 deletions src/util/MetadataController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { DataFactory, StreamParser, StreamWriter } from 'n3';
import { NamedNode, Quad } from 'rdf-js';
import streamifyArray from 'streamify-array';
import { LDP, RDF, STAT, TERMS, XML } from './Prefixes';
import { pipeStreams } from './Util';

export const TYPE_PREDICATE = DataFactory.namedNode(`${RDF}type`);
export const MODIFIED_PREDICATE = DataFactory.namedNode(`${TERMS}modified`);
Expand Down Expand Up @@ -69,7 +70,7 @@ export class MetadataController {
* @returns The Readable object.
*/
public generateReadableFromQuads(quads: Quad[]): Readable {
return streamifyArray(quads).pipe(new StreamWriter({ format: 'text/turtle' }));
return pipeStreams(streamifyArray(quads), new StreamWriter({ format: 'text/turtle' }));
}

/**
Expand All @@ -79,6 +80,6 @@ export class MetadataController {
* @returns A promise containing the array of quads.
*/
public async generateQuadsFromReadable(readable: Readable): Promise<Quad[]> {
return arrayifyStream(readable.pipe(new StreamParser({ format: 'text/turtle' })));
return await arrayifyStream(pipeStreams(readable, new StreamParser({ format: 'text/turtle' })));
}
}
17 changes: 16 additions & 1 deletion src/util/Util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Readable } from 'stream';
import { Readable, Duplex } from 'stream';
import arrayifyStream from 'arrayify-stream';
import { UnsupportedHttpError } from './errors/UnsupportedHttpError';

/**
* Makes sure the input path has exactly 1 slash at the end.
Expand Down Expand Up @@ -51,3 +52,17 @@ export const matchingMediaType = (mediaA: string, mediaB: string): boolean => {
}
return subTypeA === subTypeB;
};

/**
* Will pipe two streams.
* Makes sure an error of the first stream gets passed to the second.
* @param readable - Initial readable stream.
* @param destination - The destination for writing data.
*
* @returns destination as a Readable.
*/
export const pipeStreams = (readable: Readable, destination: Duplex): Readable => {
readable.pipe(destination);
readable.on('error', (error): boolean => destination.emit('error', new UnsupportedHttpError(error.message)));
return destination;
};
5 changes: 3 additions & 2 deletions test/unit/storage/FileResourceStore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ describe('A FileResourceStore', (): void => {
stats.isFile = jest.fn((): any => true);
(fsPromises.lstat as jest.Mock).mockReturnValueOnce(stats);
(fs.createReadStream as jest.Mock).mockReturnValueOnce(streamifyArray([ rawData ]));
(fs.createReadStream as jest.Mock).mockImplementationOnce((): any => new Error('Metadata file does not exist.'));
(fs.createReadStream as jest.Mock).mockReturnValueOnce(streamifyArray([]));

// Tests
await store.setRepresentation({ path: `${base}file.txt` }, representation);
Expand Down Expand Up @@ -488,7 +488,8 @@ describe('A FileResourceStore', (): void => {
stats.isFile = jest.fn((): any => true);
(fsPromises.lstat as jest.Mock).mockReturnValueOnce(stats);
(fs.createReadStream as jest.Mock).mockReturnValueOnce(streamifyArray([ rawData ]));
(fs.createReadStream as jest.Mock).mockImplementationOnce((): any => new Error('Metadata file does not exist.'));
(fs.createReadStream as jest.Mock).mockReturnValueOnce(new Readable()
.destroy(new Error('Metadata file does not exist.')));

const result = await store.getRepresentation({ path: `${base}.htaccess` });
expect(result).toEqual({
Expand Down

0 comments on commit 2646c88

Please sign in to comment.