diff --git a/src/index.ts b/src/index.ts index c702d3b02..33da51232 100644 --- a/src/index.ts +++ b/src/index.ts @@ -73,7 +73,6 @@ export * from './ldp/permissions/SparqlPatchPermissionsExtractor'; // LDP/Representation export * from './ldp/representation/Representation'; export * from './ldp/representation/RepresentationMetadata'; -export * from './ldp/representation/RepresentationPreference'; export * from './ldp/representation/RepresentationPreferences'; export * from './ldp/representation/ResourceIdentifier'; diff --git a/src/ldp/representation/RepresentationPreference.ts b/src/ldp/representation/RepresentationPreference.ts deleted file mode 100644 index a8ce0e117..000000000 --- a/src/ldp/representation/RepresentationPreference.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Represents preferred values along a single content negotiation dimension. - * - * The number represents how preferred this value is from 0 to 1. - * Follows the quality values rule from RFC 7231: - * "The weight is normalized to a real number in the range 0 through 1, - * where 0.001 is the least preferred and 1 is the most preferred; a - * value of 0 means "not acceptable"." - */ -export type RepresentationPreference = Record; diff --git a/src/ldp/representation/RepresentationPreferences.ts b/src/ldp/representation/RepresentationPreferences.ts index 02d5e593c..b11c1c4eb 100644 --- a/src/ldp/representation/RepresentationPreferences.ts +++ b/src/ldp/representation/RepresentationPreferences.ts @@ -1,12 +1,24 @@ -import type { RepresentationPreference } from './RepresentationPreference'; +/** + * Represents preferred values along a single content negotiation dimension. + * + * The number represents how preferred this value is from 0 to 1. + * Follows the quality values rule from RFC 7231: + * "The weight is normalized to a real number in the range 0 through 1, + * where 0.001 is the least preferred and 1 is the most preferred; a + * value of 0 means "not acceptable"." + */ +export type ValuePreferences = Record; /** - * Contains the preferences of which kind of representation is requested. + * Contains preferences along multiple content negotiation dimensions. + * + * All dimensions are optional for ease of constructing; either `undefined` + * or an empty `ValuePreferences` can indicate that no preferences were specified. */ export interface RepresentationPreferences { - type?: RepresentationPreference; - charset?: RepresentationPreference; - datetime?: RepresentationPreference; - encoding?: RepresentationPreference; - language?: RepresentationPreference; + type?: ValuePreferences; + charset?: ValuePreferences; + datetime?: ValuePreferences; + encoding?: ValuePreferences; + language?: ValuePreferences; } diff --git a/src/storage/conversion/ChainedConverter.ts b/src/storage/conversion/ChainedConverter.ts index 52dc04f4e..aa3f02ef0 100644 --- a/src/storage/conversion/ChainedConverter.ts +++ b/src/storage/conversion/ChainedConverter.ts @@ -1,4 +1,5 @@ import type { Representation } from '../../ldp/representation/Representation'; +import type { ValuePreferences } from '../../ldp/representation/RepresentationPreferences'; import { getLoggerFor } from '../../logging/LogUtil'; import { supportsConversion, matchesMediaType } from './ConversionUtil'; import type { RepresentationConverterArgs } from './RepresentationConverter'; @@ -34,24 +35,24 @@ export class ChainedConverter extends TypedRepresentationConverter { return this.converters[this.converters.length - 1]; } - public async getInputTypes(): Promise> { + public async getInputTypes(): Promise { return this.first.getInputTypes(); } - public async getOutputTypes(): Promise> { + public async getOutputTypes(): Promise { return this.last.getOutputTypes(); } public async canHandle(input: RepresentationConverterArgs): Promise { // We assume a chain can be constructed, otherwise there would be a configuration issue // So we only check if the input can be parsed and the preferred type can be written - const inTypes = this.filterTypes(await this.first.getInputTypes()); - const outTypes = this.filterTypes(await this.last.getOutputTypes()); + const inTypes = this.getAcceptableTypes(await this.first.getInputTypes()); + const outTypes = this.getAcceptableTypes(await this.last.getOutputTypes()); supportsConversion(input, inTypes, outTypes); } - private filterTypes(typeVals: Record): string[] { - return Object.keys(typeVals).filter((name): boolean => typeVals[name] > 0); + private getAcceptableTypes(preferences: ValuePreferences): string[] { + return Object.keys(preferences).filter((name): boolean => preferences[name] > 0); } public async handle(input: RepresentationConverterArgs): Promise { diff --git a/src/storage/conversion/QuadToRdfConverter.ts b/src/storage/conversion/QuadToRdfConverter.ts index eb61fb4b1..0f9a8ffa9 100644 --- a/src/storage/conversion/QuadToRdfConverter.ts +++ b/src/storage/conversion/QuadToRdfConverter.ts @@ -2,8 +2,10 @@ import type { Readable } from 'stream'; import rdfSerializer from 'rdf-serialize'; import type { Representation } from '../../ldp/representation/Representation'; import { RepresentationMetadata } from '../../ldp/representation/RepresentationMetadata'; -import type { RepresentationPreference } from '../../ldp/representation/RepresentationPreference'; -import type { RepresentationPreferences } from '../../ldp/representation/RepresentationPreferences'; +import type { + ValuePreferences, + RepresentationPreferences, +} from '../../ldp/representation/RepresentationPreferences'; import { INTERNAL_QUADS } from '../../util/ContentTypes'; import { guardStream } from '../../util/GuardedStream'; import { CONTENT_TYPE } from '../../util/Vocabularies'; @@ -15,11 +17,11 @@ import { TypedRepresentationConverter } from './TypedRepresentationConverter'; * Converts `internal/quads` to most major RDF serializations. */ export class QuadToRdfConverter extends TypedRepresentationConverter { - public async getInputTypes(): Promise { + public async getInputTypes(): Promise { return { [INTERNAL_QUADS]: 1 }; } - public async getOutputTypes(): Promise { + public async getOutputTypes(): Promise { return rdfSerializer.getContentTypesPrioritized(); } diff --git a/src/storage/conversion/RdfToQuadConverter.ts b/src/storage/conversion/RdfToQuadConverter.ts index 12c06f55a..c5a26e08b 100644 --- a/src/storage/conversion/RdfToQuadConverter.ts +++ b/src/storage/conversion/RdfToQuadConverter.ts @@ -2,6 +2,7 @@ import { PassThrough } from 'stream'; import rdfParser from 'rdf-parse'; import type { Representation } from '../../ldp/representation/Representation'; import { RepresentationMetadata } from '../../ldp/representation/RepresentationMetadata'; +import type { ValuePreferences } from '../../ldp/representation/RepresentationPreferences'; import { INTERNAL_QUADS } from '../../util/ContentTypes'; import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError'; import { pipeSafely } from '../../util/StreamUtil'; @@ -13,11 +14,11 @@ import { TypedRepresentationConverter } from './TypedRepresentationConverter'; * Converts most major RDF serializations to `internal/quads`. */ export class RdfToQuadConverter extends TypedRepresentationConverter { - public async getInputTypes(): Promise> { + public async getInputTypes(): Promise { return rdfParser.getContentTypesPrioritized(); } - public async getOutputTypes(): Promise> { + public async getOutputTypes(): Promise { return { [INTERNAL_QUADS]: 1 }; } diff --git a/src/storage/conversion/TypedRepresentationConverter.ts b/src/storage/conversion/TypedRepresentationConverter.ts index 31c8ed045..600782ec8 100644 --- a/src/storage/conversion/TypedRepresentationConverter.ts +++ b/src/storage/conversion/TypedRepresentationConverter.ts @@ -1,4 +1,4 @@ -import type { RepresentationPreference } from '../../ldp/representation/RepresentationPreference'; +import type { ValuePreferences } from '../../ldp/representation/RepresentationPreferences'; import { supportsConversion } from './ConversionUtil'; import { RepresentationConverter } from './RepresentationConverter'; import type { RepresentationConverterArgs } from './RepresentationConverter'; @@ -10,12 +10,12 @@ export abstract class TypedRepresentationConverter extends RepresentationConvert /** * Gets the supported input content types for this converter, mapped to a numerical priority. */ - public abstract getInputTypes(): Promise; + public abstract getInputTypes(): Promise; /** * Gets the supported output content types for this converter, mapped to a numerical quality. */ - public abstract getOutputTypes(): Promise; + public abstract getOutputTypes(): Promise; /** * Verifies whether this converter supports the input. diff --git a/test/unit/storage/conversion/ChainedConverter.test.ts b/test/unit/storage/conversion/ChainedConverter.test.ts index f3cba3309..daf502183 100644 --- a/test/unit/storage/conversion/ChainedConverter.test.ts +++ b/test/unit/storage/conversion/ChainedConverter.test.ts @@ -1,6 +1,9 @@ import type { Representation } from '../../../../src/ldp/representation/Representation'; import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata'; -import type { RepresentationPreferences } from '../../../../src/ldp/representation/RepresentationPreferences'; +import type { + ValuePreferences, + RepresentationPreferences, +} from '../../../../src/ldp/representation/RepresentationPreferences'; import { ChainedConverter } from '../../../../src/storage/conversion/ChainedConverter'; import { supportsConversion } from '../../../../src/storage/conversion/ConversionUtil'; import type { RepresentationConverterArgs } from '../../../../src/storage/conversion/RepresentationConverter'; @@ -8,20 +11,20 @@ import { TypedRepresentationConverter } from '../../../../src/storage/conversion import { CONTENT_TYPE } from '../../../../src/util/Vocabularies'; class DummyConverter extends TypedRepresentationConverter { - private readonly inTypes: Record; - private readonly outTypes: Record; + private readonly inTypes: ValuePreferences; + private readonly outTypes: ValuePreferences; - public constructor(inTypes: Record, outTypes: Record) { + public constructor(inTypes: ValuePreferences, outTypes: ValuePreferences) { super(); this.inTypes = inTypes; this.outTypes = outTypes; } - public async getInputTypes(): Promise> { + public async getInputTypes(): Promise { return this.inTypes; } - public async getOutputTypes(): Promise> { + public async getOutputTypes(): Promise { return this.outTypes; }