mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
refactor: Add isContainerPath function
This commit is contained in:
parent
1073c2ff4c
commit
75e4f73c3f
@ -12,7 +12,13 @@ import { MethodNotAllowedHttpError } from '../util/errors/MethodNotAllowedHttpEr
|
||||
import { NotFoundHttpError } from '../util/errors/NotFoundHttpError';
|
||||
import { NotImplementedError } from '../util/errors/NotImplementedError';
|
||||
import { UnsupportedHttpError } from '../util/errors/UnsupportedHttpError';
|
||||
import { ensureTrailingSlash, getParentContainer, trimTrailingSlashes } from '../util/PathUtil';
|
||||
import {
|
||||
ensureTrailingSlash,
|
||||
getParentContainer,
|
||||
isContainerIdentifier,
|
||||
isContainerPath,
|
||||
trimTrailingSlashes,
|
||||
} from '../util/PathUtil';
|
||||
import { parseQuads } from '../util/QuadUtil';
|
||||
import { generateResourceQuads } from '../util/ResourceUtil';
|
||||
import { CONTENT_TYPE, HTTP, LDP, RDF } from '../util/UriConstants';
|
||||
@ -93,7 +99,7 @@ export class DataAccessorBasedStore implements ResourceStore {
|
||||
|
||||
// When a POST method request targets a non-container resource without an existing representation,
|
||||
// the server MUST respond with the 404 status code.
|
||||
if (!parentMetadata && !container.path.endsWith('/')) {
|
||||
if (!parentMetadata && !isContainerIdentifier(container)) {
|
||||
throw new NotFoundHttpError();
|
||||
}
|
||||
|
||||
@ -104,7 +110,7 @@ export class DataAccessorBasedStore implements ResourceStore {
|
||||
const newID = this.createSafeUri(container, representation.metadata, parentMetadata);
|
||||
|
||||
// Write the data. New containers will need to be created if there is no parent.
|
||||
await this.writeData(newID, representation, newID.path.endsWith('/'), !parentMetadata);
|
||||
await this.writeData(newID, representation, isContainerIdentifier(newID), !parentMetadata);
|
||||
|
||||
return newID;
|
||||
}
|
||||
@ -128,7 +134,7 @@ export class DataAccessorBasedStore implements ResourceStore {
|
||||
if (oldMetadata && isContainer !== this.isExistingContainer(oldMetadata)) {
|
||||
throw new ConflictHttpError('Input resource type does not match existing resource type.');
|
||||
}
|
||||
if (isContainer !== identifier.path.endsWith('/')) {
|
||||
if (isContainer !== isContainerIdentifier(identifier)) {
|
||||
throw new UnsupportedHttpError('Containers should have a `/` at the end of their path, resources should not.');
|
||||
}
|
||||
|
||||
@ -172,7 +178,7 @@ export class DataAccessorBasedStore implements ResourceStore {
|
||||
* @param identifier - Identifier that needs to be checked.
|
||||
*/
|
||||
protected async getNormalizedMetadata(identifier: ResourceIdentifier): Promise<RepresentationMetadata> {
|
||||
const hasSlash = identifier.path.endsWith('/');
|
||||
const hasSlash = isContainerIdentifier(identifier);
|
||||
try {
|
||||
return await this.accessor.getMetadata(identifier);
|
||||
} catch (error: unknown) {
|
||||
@ -312,7 +318,7 @@ export class DataAccessorBasedStore implements ResourceStore {
|
||||
isContainer = this.isExistingContainer(metadata);
|
||||
} catch {
|
||||
const slug = suffix ?? metadata.get(HTTP.slug)?.value;
|
||||
isContainer = Boolean(slug?.endsWith('/'));
|
||||
isContainer = Boolean(slug && isContainerPath(slug));
|
||||
}
|
||||
return isContainer;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
decodeUriPathComponents,
|
||||
encodeUriPathComponents,
|
||||
ensureTrailingSlash,
|
||||
isContainerIdentifier,
|
||||
trimTrailingSlashes,
|
||||
} from '../util/PathUtil';
|
||||
import type { FileIdentifierMapper, ResourceLink } from './FileIdentifierMapper';
|
||||
@ -74,7 +75,7 @@ export class ExtensionBasedMapper implements FileIdentifierMapper {
|
||||
let filePath = this.getAbsolutePath(path);
|
||||
|
||||
// Container
|
||||
if (identifier.path.endsWith('/')) {
|
||||
if (isContainerIdentifier(identifier)) {
|
||||
this.logger.debug(`URL ${identifier.path} points to the container ${filePath}`);
|
||||
return {
|
||||
identifier,
|
||||
|
@ -12,6 +12,7 @@ import { ConflictHttpError } from '../../util/errors/ConflictHttpError';
|
||||
import { NotFoundHttpError } from '../../util/errors/NotFoundHttpError';
|
||||
import { isSystemError } from '../../util/errors/SystemError';
|
||||
import { UnsupportedMediaTypeHttpError } from '../../util/errors/UnsupportedMediaTypeHttpError';
|
||||
import { isContainerIdentifier } from '../../util/PathUtil';
|
||||
import { parseQuads, pushQuad, serializeQuads } from '../../util/QuadUtil';
|
||||
import { generateContainmentQuads, generateResourceQuads } from '../../util/ResourceUtil';
|
||||
import { CONTENT_TYPE, DCTERMS, POSIX, RDF, XSD } from '../../util/UriConstants';
|
||||
@ -62,10 +63,10 @@ export class FileDataAccessor implements DataAccessor {
|
||||
public async getMetadata(identifier: ResourceIdentifier): Promise<RepresentationMetadata> {
|
||||
const link = await this.resourceMapper.mapUrlToFilePath(identifier);
|
||||
const stats = await this.getStats(link.filePath);
|
||||
if (!identifier.path.endsWith('/') && stats.isFile()) {
|
||||
if (!isContainerIdentifier(identifier) && stats.isFile()) {
|
||||
return this.getFileMetadata(link, stats);
|
||||
}
|
||||
if (identifier.path.endsWith('/') && stats.isDirectory()) {
|
||||
if (isContainerIdentifier(identifier) && stats.isDirectory()) {
|
||||
return this.getDirectoryMetadata(link, stats);
|
||||
}
|
||||
throw new NotFoundHttpError();
|
||||
@ -131,9 +132,9 @@ export class FileDataAccessor implements DataAccessor {
|
||||
}
|
||||
}
|
||||
|
||||
if (!identifier.path.endsWith('/') && stats.isFile()) {
|
||||
if (!isContainerIdentifier(identifier) && stats.isFile()) {
|
||||
await fsPromises.unlink(link.filePath);
|
||||
} else if (identifier.path.endsWith('/') && stats.isDirectory()) {
|
||||
} else if (isContainerIdentifier(identifier) && stats.isDirectory()) {
|
||||
await fsPromises.rmdir(link.filePath);
|
||||
} else {
|
||||
throw new NotFoundHttpError();
|
||||
|
@ -5,7 +5,7 @@ import type { NamedNode } from 'rdf-js';
|
||||
import { RepresentationMetadata } from '../../ldp/representation/RepresentationMetadata';
|
||||
import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier';
|
||||
import { NotFoundHttpError } from '../../util/errors/NotFoundHttpError';
|
||||
import { ensureTrailingSlash } from '../../util/PathUtil';
|
||||
import { ensureTrailingSlash, isContainerIdentifier } from '../../util/PathUtil';
|
||||
import { generateContainmentQuads, generateResourceQuads } from '../../util/ResourceUtil';
|
||||
import type { DataAccessor } from './DataAccessor';
|
||||
|
||||
@ -66,7 +66,7 @@ export class InMemoryDataAccessor implements DataAccessor {
|
||||
|
||||
public async getMetadata(identifier: ResourceIdentifier): Promise<RepresentationMetadata> {
|
||||
const entry = this.getEntry(identifier);
|
||||
if (this.isDataEntry(entry) === identifier.path.endsWith('/')) {
|
||||
if (this.isDataEntry(entry) === isContainerIdentifier(identifier)) {
|
||||
throw new NotFoundHttpError();
|
||||
}
|
||||
return this.generateMetadata(identifier, entry);
|
||||
|
@ -23,7 +23,7 @@ import { ConflictHttpError } from '../../util/errors/ConflictHttpError';
|
||||
import { NotFoundHttpError } from '../../util/errors/NotFoundHttpError';
|
||||
import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError';
|
||||
import { UnsupportedMediaTypeHttpError } from '../../util/errors/UnsupportedMediaTypeHttpError';
|
||||
import { ensureTrailingSlash, getParentContainer } from '../../util/PathUtil';
|
||||
import { ensureTrailingSlash, getParentContainer, isContainerIdentifier } from '../../util/PathUtil';
|
||||
import { generateResourceQuads } from '../../util/ResourceUtil';
|
||||
import { CONTENT_TYPE, LDP } from '../../util/UriConstants';
|
||||
import { toNamedNode } from '../../util/UriUtil';
|
||||
@ -81,7 +81,7 @@ export class SparqlDataAccessor implements DataAccessor {
|
||||
*/
|
||||
public async getMetadata(identifier: ResourceIdentifier): Promise<RepresentationMetadata> {
|
||||
const name = namedNode(identifier.path);
|
||||
const query = identifier.path.endsWith('/') ?
|
||||
const query = isContainerIdentifier(identifier) ?
|
||||
this.sparqlConstructContainer(name) :
|
||||
this.sparqlConstruct(this.getMetadataNode(name));
|
||||
const stream = await this.sendSparqlConstruct(query);
|
||||
|
@ -58,3 +58,15 @@ export const getParentContainer = (id: ResourceIdentifier): ResourceIdentifier =
|
||||
|
||||
return { path: parentPath };
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the path corresponds to a container path (ending in a /).
|
||||
* @param path - Path to check.
|
||||
*/
|
||||
export const isContainerPath = (path: string): boolean => path.endsWith('/');
|
||||
|
||||
/**
|
||||
* Checks if the identifier corresponds to a container identifier.
|
||||
* @param identifier - Identifier to check.
|
||||
*/
|
||||
export const isContainerIdentifier = (identifier: ResourceIdentifier): boolean => isContainerPath(identifier.path);
|
||||
|
Loading…
x
Reference in New Issue
Block a user