mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
54 lines
2.1 KiB
TypeScript
54 lines
2.1 KiB
TypeScript
import { URL } from 'url';
|
|
import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier';
|
|
import { errorTermsToMetadata } from '../errors/HttpErrorUtil';
|
|
import { InternalServerError } from '../errors/InternalServerError';
|
|
import { ensureTrailingSlash, isContainerIdentifier } from '../PathUtil';
|
|
import type { IdentifierStrategy } from './IdentifierStrategy';
|
|
|
|
/**
|
|
* Provides a default implementation for `getParentContainer`
|
|
* which checks if the identifier is supported and not a root container.
|
|
* If not, the last part before the first relevant slash will be removed to find the parent.
|
|
*
|
|
* Provides a default implementation for `contains`
|
|
* which does standard slash-semantics based string comparison.
|
|
*/
|
|
export abstract class BaseIdentifierStrategy implements IdentifierStrategy {
|
|
public abstract supportsIdentifier(identifier: ResourceIdentifier): boolean;
|
|
|
|
public getParentContainer(identifier: ResourceIdentifier): ResourceIdentifier {
|
|
if (!this.supportsIdentifier(identifier)) {
|
|
throw new InternalServerError(`The identifier ${identifier.path} is outside the configured identifier space.`,
|
|
{ errorCode: 'E0001', metadata: errorTermsToMetadata({ path: identifier.path }) });
|
|
}
|
|
if (this.isRootContainer(identifier)) {
|
|
throw new InternalServerError(`Cannot obtain the parent of ${identifier.path} because it is a root container.`);
|
|
}
|
|
|
|
// Trailing slash is necessary for URL library
|
|
const parentPath = new URL('..', ensureTrailingSlash(identifier.path)).href;
|
|
|
|
return { path: parentPath };
|
|
}
|
|
|
|
public abstract isRootContainer(identifier: ResourceIdentifier): boolean;
|
|
|
|
public contains(container: ResourceIdentifier, identifier: ResourceIdentifier, transitive: boolean): boolean {
|
|
if (!isContainerIdentifier(container)) {
|
|
return false;
|
|
}
|
|
|
|
if (!identifier.path.startsWith(container.path)) {
|
|
return false;
|
|
}
|
|
|
|
if (transitive) {
|
|
return true;
|
|
}
|
|
|
|
const tail = identifier.path.slice(container.path.length);
|
|
// If there is at least one `/` followed by a char this is not a direct parent container
|
|
return !/\/./u.test(tail);
|
|
}
|
|
}
|