@sitecore/sc-contenthub-webclient-sdk
Version:
Sitecore Content Hub WebClient SDK.
236 lines • 13.4 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import format from "string-format";
import { RelationBase } from "../contracts/base/relation";
import { RelationCardinality } from "../contracts/base/relation-cardinality";
import { RelationRole } from "../contracts/base/relation-role";
import { ChildToManyParentsRelation } from "../contracts/base/relations/child-to-many-parents-relation";
import { ChildToOneParentRelation } from "../contracts/base/relations/child-to-one-parent-relation";
import { ParentToManyChildrenRelation } from "../contracts/base/relations/parent-to-many-children-relation";
import { ParentToOneChildRelation } from "../contracts/base/relations/parent-to-one-child-relation";
import { MinimalSchema } from "../contracts/querying/minimal-schema";
import { RelationData } from "../contracts/querying/relation-data";
import { EntityLink } from "../entity-link";
import ErrorMessages from "../error-messages";
import { InternalError } from "../errors/internal-error";
import { NotSupportedError } from "../errors/not-supported-error";
import Guard from "../guard";
import { RelationResource } from "../models/relation-resource";
export class RelationMapper {
constructor(client) {
Guard.notNullOrUndefined(client);
this._client = client;
}
mapRelationsAsync(resource, schema) {
return __awaiter(this, void 0, void 0, function* () {
Guard.notNullOrUndefined(resource);
const list = [];
// If no minimal schema is available, build it from the definition.
if (schema == null) {
const definitionName = yield this._client.linkHelper.nameFromDefinitionAsync(resource.entityDefinition);
if (definitionName == null) {
throw new InternalError(`Could not resolve definition name from entity resource.`);
}
const definition = yield this._client.entityDefinitions.getCachedAsync(definitionName);
if (definition == null) {
throw new InternalError(`Could not load definition with name '${definitionName}.`);
}
schema = new MinimalSchema(definitionName);
const loadedRelations = Object.keys(resource.relations);
schema.relations = definition
.getRelationDefinitions()
.filter(relationDefinition => loadedRelations.includes(relationDefinition.name))
.map(relationDefinition => new RelationData({
name: relationDefinition.name,
cardinality: relationDefinition.cardinality,
role: relationDefinition.role,
}));
}
for (const relation of schema.relations) {
const name = relation.name;
const cardinality = relation.cardinality;
const role = relation.role;
// Try to get the relation, it is on the schema, so it should be there.
const relationObject = resource.relations[name];
if (!relationObject) {
const msg = `[Internal] Relation with name '${relation.name}' was on schema, but not on the entity resource.`;
this._client.logger.warn(msg);
continue;
}
const isRelationResource = relationObject instanceof RelationResource;
const relationResource = relationObject;
// The relation should be nested, so we can use it as a RelationResource
if (!isRelationResource) {
const msg = `[Internal] Relation with name '${relation.name}' was on the entity resource, but the relation was not nested.`;
this._client.logger.warn(msg);
continue;
}
let result = null;
if (role == RelationRole.Parent) {
if (cardinality == RelationCardinality.ManyToMany || cardinality == RelationCardinality.OneToMany) {
let subRelation;
if (relationResource.children != null) {
const ids = [];
const properties = {};
for (const r of relationResource.children) {
const id = yield this._client.linkHelper.idFromEntityAsync(r);
ids.push(id);
properties[id] = r.properties;
}
subRelation = new ParentToManyChildrenRelation(name, properties, this._client, relationResource.childTotal);
subRelation.setIds(ids);
}
else {
subRelation = new ParentToManyChildrenRelation(name, null, this._client, relationResource.childTotal);
}
result = subRelation;
}
else if (cardinality == RelationCardinality.OneToOne) {
let childId = null;
const properties = {};
if (relationResource.child != null) {
childId = yield this._client.linkHelper.idFromEntityAsync(relationResource.child);
properties[childId] = relationResource.child.properties;
}
else if (relationResource.children instanceof Array && relationResource.children.length) {
childId = yield this._client.linkHelper.idFromEntityAsync(relationResource.children[0]);
properties[childId] = relationResource.children[0].properties;
}
const subRelation = new ParentToOneChildRelation(name, properties, this._client);
subRelation.child = childId;
result = subRelation;
}
}
else if (role == RelationRole.Child) {
if (cardinality == RelationCardinality.ManyToMany) {
let subRelation;
if (relationResource.parents != null) {
const ids = [];
const properties = {};
for (const r of relationResource.parents) {
const id = yield this._client.linkHelper.idFromEntityAsync(r);
ids.push(id);
properties[id] = r.properties;
}
subRelation = new ChildToManyParentsRelation(name, properties, this._client, relationResource.parentTotal, relationResource.inheritsSecurity);
subRelation.setIds(ids);
}
else {
subRelation = new ChildToManyParentsRelation(name, null, this._client, relationResource.parentTotal, relationResource.inheritsSecurity);
}
result = subRelation;
}
else if (cardinality == RelationCardinality.OneToOne ||
cardinality == RelationCardinality.OneToMany) {
let parentId = null;
const properties = {};
if (relationResource.parent != null) {
parentId = yield this._client.linkHelper.idFromEntityAsync(relationResource.parent);
properties[parentId] = relationResource.parent.properties;
}
else if (relationResource.parents instanceof Array && relationResource.parents.length) {
parentId = yield this._client.linkHelper.idFromEntityAsync(relationResource.parents[0]);
properties[parentId] = relationResource.parents[0].properties;
}
const subRelation = new ChildToOneParentRelation(name, properties, this._client, relationResource.inheritsSecurity);
subRelation.parent = parentId;
result = subRelation;
}
}
if (result == null) {
const msg = format(ErrorMessages.UnsupportedRelation, RelationCardinality[relation.cardinality], RelationRole[relation.role]);
throw new Error(msg);
}
list.push(result);
}
return list;
});
}
mapToRelationResourcesAsync(entity) {
return __awaiter(this, void 0, void 0, function* () {
Guard.notNullOrUndefined(entity);
return yield this.mapRelationsToResourcesAsync([...entity.relations], entity.id || 0);
});
}
mapRelationToResourceAsync(relation, id) {
return __awaiter(this, void 0, void 0, function* () {
Guard.notNullOrUndefined(relation);
const resource = new RelationResource();
if (RelationBase.isChildRelation(relation)) {
resource.inheritsSecurity = relation.inheritsSecurity;
}
if (RelationBase.isChildToManyParentsRelation(relation)) {
const parentLinks = yield this._client.linkHelper.entitiesToLinksAsync(relation.parents);
resource.parents = parentLinks.map((link, index) => {
const parent = new EntityLink(link.href);
parent.properties = relation.properties[relation.parents[index]];
return parent;
});
}
else if (RelationBase.isChildToOneParentRelation(relation)) {
if (relation.parent) {
const link = yield this._client.linkHelper.entityToLinkAsync(relation.parent);
resource.parent = new EntityLink(link.href);
resource.parent.properties = relation.properties[relation.parent];
}
}
else if (RelationBase.isParentToManyChildrenRelation(relation)) {
const childLinks = yield this._client.linkHelper.entitiesToLinksAsync(relation.children);
resource.children = childLinks.map(link => new EntityLink(link.href));
resource.children = childLinks.map((link, index) => {
const child = new EntityLink(link.href);
child.properties = relation.properties[relation.children[index]];
return child;
});
}
else if (RelationBase.isParentToOneChildRelation(relation)) {
if (relation.child) {
const link = yield this._client.linkHelper.entityToLinkAsync(relation.child);
resource.child = new EntityLink(link.href);
resource.child.properties = relation.properties[relation.child];
}
}
else {
throw new NotSupportedError("Unknown relation type.");
}
const relationLink = yield this._client.linkHelper.relationToLinkAsync(id, relation.name);
resource.self = relationLink;
return resource;
});
}
mapDirtyRelationsAsync(entity) {
return __awaiter(this, void 0, void 0, function* () {
Guard.notNullOrUndefined(entity);
const relationNames = entity.relations.reduce((a, r) => (r.isDirty && a.push(r.name), a), []);
const relations = entity.relations.filter(relation => relationNames.includes(relation.name));
const dict = yield this.mapRelationsToResourcesAsync(relations, entity.id || 0);
return dict;
});
}
mapRelationsToResourcesAsync(relations, id) {
return __awaiter(this, void 0, void 0, function* () {
Guard.notNullOrUndefined(relations);
const dict = {};
for (const relation of relations) {
const mappedRelation = yield this.mapRelationToResourceAsync(relation, id);
if (dict[relation.name]) {
const existing = dict[relation.name];
const merged = RelationResource.merge(existing, mappedRelation);
dict[relation.name] = merged;
}
else {
dict[relation.name] = mappedRelation;
}
}
return dict;
});
}
}
//# sourceMappingURL=relation-mapper.js.map