CommunitySolidServer/src/storage/RepresentationConvertingStore.ts
smessie 99464d9a95
feat: Add logging
* feat: Add logging

* refactor: Configure the logger for the tests once globally

* feat: Add logging

* fix: Fix ESLint errors due to merge conflicts

* Review log and error messages.

* refactor: Cleanup a bit

* refactor: Change to logger info calls

Co-authored-by: Ruben Verborgh <ruben@verborgh.org>
2020-10-26 10:31:01 +01:00

53 lines
2.3 KiB
TypeScript

import type { Representation } from '../ldp/representation/Representation';
import type { RepresentationPreferences } from '../ldp/representation/RepresentationPreferences';
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
import { getLoggerFor } from '../logging/LogUtil';
import { matchingMediaType } from '../util/Util';
import type { Conditions } from './Conditions';
import type { RepresentationConverter } from './conversion/RepresentationConverter';
import { PassthroughStore } from './PassthroughStore';
import type { ResourceStore } from './ResourceStore';
/**
* Store that overrides the `getRepresentation` function.
* Tries to convert the {@link Representation} it got from the source store
* so it matches one of the given type preferences.
*
* In the future this class should take the preferences of the request into account.
* Even if there is a match with the output from the store,
* if there is a low weight for that type conversions might still be preferred.
*/
export class RepresentationConvertingStore<T extends ResourceStore = ResourceStore> extends PassthroughStore<T> {
protected readonly logger = getLoggerFor(this);
private readonly converter: RepresentationConverter;
public constructor(source: T, converter: RepresentationConverter) {
super(source);
this.converter = converter;
}
public async getRepresentation(identifier: ResourceIdentifier, preferences: RepresentationPreferences,
conditions?: Conditions): Promise<Representation> {
const representation = await super.getRepresentation(identifier, preferences, conditions);
if (this.matchesPreferences(representation, preferences)) {
return representation;
}
this.logger.info(`Convert ${identifier.path} from ${representation.metadata.contentType} to ${preferences.type}`);
return this.converter.handleSafe({ identifier, representation, preferences });
}
private matchesPreferences(representation: Representation, preferences: RepresentationPreferences): boolean {
if (!preferences.type) {
return true;
}
const { contentType } = representation.metadata;
return Boolean(
contentType &&
preferences.type.some((type): boolean =>
type.weight > 0 &&
matchingMediaType(type.value, contentType)),
);
}
}