refactor: Make ExtensionBasedMapper only expose what is needed

This commit is contained in:
Joachim Van Herwegen 2020-10-14 16:34:36 +02:00
parent 03c64e5617
commit 4df26454d4
3 changed files with 4 additions and 49 deletions

View File

@ -3,7 +3,6 @@ import { posix } from 'path';
import * as mime from 'mime-types';
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
import { APPLICATION_OCTET_STREAM, TEXT_TURTLE } from '../util/ContentTypes';
import { ConflictHttpError } from '../util/errors/ConflictHttpError';
import { NotFoundHttpError } from '../util/errors/NotFoundHttpError';
import { UnsupportedHttpError } from '../util/errors/UnsupportedHttpError';
import {
@ -202,34 +201,10 @@ export class ExtensionBasedMapper implements FileIdentifierMapper {
*
* @returns A string representing the relative path.
*/
public getRelativePath(identifier: ResourceIdentifier): string {
private getRelativePath(identifier: ResourceIdentifier): string {
if (!identifier.path.startsWith(this.baseRequestURI)) {
throw new NotFoundHttpError();
}
return decodeUriPathComponents(identifier.path.slice(this.baseRequestURI.length));
}
/**
* Splits the identifier into the parent directory and slug.
* If the identifier specifies a directory, slug will be undefined.
* @param identifier - Incoming identifier.
*
* @throws {@link ConflictHttpError}
* If the root identifier is passed.
*
* @returns A ResourcePath object containing (absolute) path and (optional) slug fields.
*/
public extractDocumentName(identifier: ResourceIdentifier): ResourcePath {
const [ , containerPath, documentName ] = /^(.*\/)([^/]+\/?)?$/u.exec(this.getRelativePath(identifier)) ?? [];
if (
(typeof containerPath !== 'string' || normalizePath(containerPath) === '/') && typeof documentName !== 'string') {
throw new ConflictHttpError('Container with that identifier already exists (root).');
}
return {
containerPath: this.getAbsolutePath(normalizePath(containerPath)),
// If documentName is defined, return normalized documentName
documentName: typeof documentName === 'string' ? normalizePath(documentName) : undefined,
};
}
}

View File

@ -16,8 +16,7 @@ import type { MetadataController } from '../../util/MetadataController';
import { CONTENT_TYPE, DCTERMS, POSIX, RDF, XSD } from '../../util/UriConstants';
import { toNamedNode, toTypedLiteral } from '../../util/UriUtil';
import { pushQuad } from '../../util/Util';
import type { ExtensionBasedMapper } from '../ExtensionBasedMapper';
import type { ResourceLink } from '../FileIdentifierMapper';
import type { FileIdentifierMapper, ResourceLink } from '../FileIdentifierMapper';
import type { DataAccessor } from './DataAccessor';
const { join: joinPath } = posix;
@ -26,10 +25,10 @@ const { join: joinPath } = posix;
* DataAccessor that uses the file system to store documents as files and containers as folders.
*/
export class FileDataAccessor implements DataAccessor {
private readonly resourceMapper: ExtensionBasedMapper;
private readonly resourceMapper: FileIdentifierMapper;
private readonly metadataController: MetadataController;
public constructor(resourceMapper: ExtensionBasedMapper, metadataController: MetadataController) {
public constructor(resourceMapper: FileIdentifierMapper, metadataController: MetadataController) {
this.resourceMapper = resourceMapper;
this.metadataController = metadataController;
}

View File

@ -1,6 +1,5 @@
import fs from 'fs';
import { ExtensionBasedMapper } from '../../../src/storage/ExtensionBasedMapper';
import { ConflictHttpError } from '../../../src/util/errors/ConflictHttpError';
import { NotFoundHttpError } from '../../../src/util/errors/NotFoundHttpError';
import { UnsupportedHttpError } from '../../../src/util/errors/UnsupportedHttpError';
import { trimTrailingSlashes } from '../../../src/util/Util';
@ -136,22 +135,4 @@ describe('An ExtensionBasedMapper', (): void => {
});
});
});
describe('extractDocumentName', (): void => {
it('throws an error if the input corresponds to root.', async(): Promise<void> => {
expect((): any => mapper.extractDocumentName({ path: base })).toThrow(ConflictHttpError);
expect((): any => mapper.extractDocumentName({ path: trimTrailingSlashes(base) }))
.toThrow(ConflictHttpError);
});
it('parses the identifier into container file path and document name.', async(): Promise<void> => {
expect(mapper.extractDocumentName({ path: `${base}test` })).toEqual({
containerPath: rootFilepath,
documentName: 'test',
});
expect(mapper.extractDocumentName({ path: `${base}test/` })).toEqual({
containerPath: `${rootFilepath}test/`,
});
});
});
});