@paperbits/common
Version:
Paperbits common components.
120 lines (93 loc) • 4.34 kB
text/typescript
import * as MediaUtils from "./mediaUtils";
import { IMediaService } from "./IMediaService";
import { IPermalinkResolver, HyperlinkModel } from "../permalinks";
import { MediaContract } from "./mediaContract";
import { ContentItemContract } from "../contentModel";
import { HyperlinkContract } from "../editing";
export class MediaPermalinkResolver implements IPermalinkResolver {
protected mediaPath: string = "uploads/";
constructor(private readonly mediaService: IMediaService) { }
public canHandleTarget(targetKey: string): boolean {
return targetKey.startsWith("uploads/");
}
public async getUrlByTargetKey(mediaKey: string): Promise<string> {
if (!mediaKey) {
throw new Error(`Parameter "mediaKey" not specified.`);
}
try {
const media = await this.mediaService.getMediaByKey(mediaKey);
if (!media) {
console.warn(`Could not find permalink by key ${mediaKey}.`);
return null;
}
if (media.variants?.length > 0) { // Currently this case is possible only with CDN and image optimization services.
const biggestVariant = MediaUtils.getBiggestMediaVariant(media);
return biggestVariant.downloadUrl;
}
else {
return media.permalink;
}
}
catch (error) {
console.warn(`Could not fetch permalink by key ${mediaKey}. Error: ${error.message}`);
return null;
}
}
private async getHyperlink(mediaContract: MediaContract, hyperlinkContract?: HyperlinkContract): Promise<HyperlinkModel> {
const hyperlinkModel = new HyperlinkModel();
hyperlinkModel.targetKey = mediaContract.key;
hyperlinkModel.href = mediaContract.permalink;
hyperlinkModel.title = mediaContract.fileName || mediaContract.permalink;
if (hyperlinkContract) {
hyperlinkModel.target = hyperlinkContract.target;
hyperlinkModel.anchor = hyperlinkContract.anchor;
hyperlinkModel.anchorName = hyperlinkContract.anchorName;
}
return hyperlinkModel;
}
public async getHyperlinkByTargetKey(targetKey: string): Promise<HyperlinkModel> {
if (!targetKey) {
throw new Error("Target key cannot be null or empty.");
}
if (!targetKey.startsWith(this.mediaPath)) {
return null;
}
const mediaContract = await this.mediaService.getMediaByKey(targetKey);
if (!mediaContract) {
console.warn(`Could create hyperlink for target with key ${targetKey}.`);
return null;
}
const hyperlink = await this.getHyperlink(mediaContract);
return hyperlink;
}
public async getContentItemByPermalink(permalink: string): Promise<ContentItemContract> {
if (!permalink) {
throw new Error(`Parameter "permalink" not specified.`);
}
const mediaContract = await this.mediaService.getMediaByPermalink(permalink);
return mediaContract;
}
public async getHyperlinkFromContract(hyperlinkContract: HyperlinkContract, locale?: string): Promise<HyperlinkModel> {
if (!hyperlinkContract.targetKey) {
throw new Error("Target key cannot be null or empty.");
}
if (!hyperlinkContract.targetKey.startsWith(this.mediaPath)) {
return null;
}
let hyperlinkModel: HyperlinkModel;
if (hyperlinkContract.targetKey) {
const mediaContract = await this.mediaService.getMediaByKey(hyperlinkContract.targetKey);
if (mediaContract) {
return this.getHyperlink(mediaContract, hyperlinkContract);
}
}
hyperlinkModel = new HyperlinkModel();
hyperlinkModel.title = "Unset link";
hyperlinkModel.target = hyperlinkContract.target;
hyperlinkModel.targetKey = hyperlinkContract.targetKey;
hyperlinkModel.href = "#";
hyperlinkModel.anchor = hyperlinkContract.anchor;
hyperlinkModel.anchorName = hyperlinkContract.anchorName;
return hyperlinkModel;
}
}