@sitecore/sc-contenthub-webclient-sdk
Version:
Sitecore Content Hub WebClient SDK.
243 lines • 14.6 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());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RelationMapper = void 0;
const string_format_1 = __importDefault(require("string-format"));
const relation_1 = require("../contracts/base/relation");
const relation_cardinality_1 = require("../contracts/base/relation-cardinality");
const relation_role_1 = require("../contracts/base/relation-role");
const child_to_many_parents_relation_1 = require("../contracts/base/relations/child-to-many-parents-relation");
const child_to_one_parent_relation_1 = require("../contracts/base/relations/child-to-one-parent-relation");
const parent_to_many_children_relation_1 = require("../contracts/base/relations/parent-to-many-children-relation");
const parent_to_one_child_relation_1 = require("../contracts/base/relations/parent-to-one-child-relation");
const minimal_schema_1 = require("../contracts/querying/minimal-schema");
const relation_data_1 = require("../contracts/querying/relation-data");
const entity_link_1 = require("../entity-link");
const error_messages_1 = __importDefault(require("../error-messages"));
const internal_error_1 = require("../errors/internal-error");
const not_supported_error_1 = require("../errors/not-supported-error");
const guard_1 = __importDefault(require("../guard"));
const relation_resource_1 = require("../models/relation-resource");
class RelationMapper {
constructor(client) {
guard_1.default.notNullOrUndefined(client);
this._client = client;
}
mapRelationsAsync(resource, schema) {
return __awaiter(this, void 0, void 0, function* () {
guard_1.default.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 internal_error_1.InternalError(`Could not resolve definition name from entity resource.`);
}
const definition = yield this._client.entityDefinitions.getCachedAsync(definitionName);
if (definition == null) {
throw new internal_error_1.InternalError(`Could not load definition with name '${definitionName}.`);
}
schema = new minimal_schema_1.MinimalSchema(definitionName);
const loadedRelations = Object.keys(resource.relations);
schema.relations = definition
.getRelationDefinitions()
.filter(relationDefinition => loadedRelations.includes(relationDefinition.name))
.map(relationDefinition => new relation_data_1.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 relation_resource_1.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 == relation_role_1.RelationRole.Parent) {
if (cardinality == relation_cardinality_1.RelationCardinality.ManyToMany || cardinality == relation_cardinality_1.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 parent_to_many_children_relation_1.ParentToManyChildrenRelation(name, properties, this._client, relationResource.childTotal);
subRelation.setIds(ids);
}
else {
subRelation = new parent_to_many_children_relation_1.ParentToManyChildrenRelation(name, null, this._client, relationResource.childTotal);
}
result = subRelation;
}
else if (cardinality == relation_cardinality_1.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 parent_to_one_child_relation_1.ParentToOneChildRelation(name, properties, this._client);
subRelation.child = childId;
result = subRelation;
}
}
else if (role == relation_role_1.RelationRole.Child) {
if (cardinality == relation_cardinality_1.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 child_to_many_parents_relation_1.ChildToManyParentsRelation(name, properties, this._client, relationResource.parentTotal, relationResource.inheritsSecurity);
subRelation.setIds(ids);
}
else {
subRelation = new child_to_many_parents_relation_1.ChildToManyParentsRelation(name, null, this._client, relationResource.parentTotal, relationResource.inheritsSecurity);
}
result = subRelation;
}
else if (cardinality == relation_cardinality_1.RelationCardinality.OneToOne ||
cardinality == relation_cardinality_1.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 child_to_one_parent_relation_1.ChildToOneParentRelation(name, properties, this._client, relationResource.inheritsSecurity);
subRelation.parent = parentId;
result = subRelation;
}
}
if (result == null) {
const msg = (0, string_format_1.default)(error_messages_1.default.UnsupportedRelation, relation_cardinality_1.RelationCardinality[relation.cardinality], relation_role_1.RelationRole[relation.role]);
throw new Error(msg);
}
list.push(result);
}
return list;
});
}
mapToRelationResourcesAsync(entity) {
return __awaiter(this, void 0, void 0, function* () {
guard_1.default.notNullOrUndefined(entity);
return yield this.mapRelationsToResourcesAsync([...entity.relations], entity.id || 0);
});
}
mapRelationToResourceAsync(relation, id) {
return __awaiter(this, void 0, void 0, function* () {
guard_1.default.notNullOrUndefined(relation);
const resource = new relation_resource_1.RelationResource();
if (relation_1.RelationBase.isChildRelation(relation)) {
resource.inheritsSecurity = relation.inheritsSecurity;
}
if (relation_1.RelationBase.isChildToManyParentsRelation(relation)) {
const parentLinks = yield this._client.linkHelper.entitiesToLinksAsync(relation.parents);
resource.parents = parentLinks.map((link, index) => {
const parent = new entity_link_1.EntityLink(link.href);
parent.properties = relation.properties[relation.parents[index]];
return parent;
});
}
else if (relation_1.RelationBase.isChildToOneParentRelation(relation)) {
if (relation.parent) {
const link = yield this._client.linkHelper.entityToLinkAsync(relation.parent);
resource.parent = new entity_link_1.EntityLink(link.href);
resource.parent.properties = relation.properties[relation.parent];
}
}
else if (relation_1.RelationBase.isParentToManyChildrenRelation(relation)) {
const childLinks = yield this._client.linkHelper.entitiesToLinksAsync(relation.children);
resource.children = childLinks.map(link => new entity_link_1.EntityLink(link.href));
resource.children = childLinks.map((link, index) => {
const child = new entity_link_1.EntityLink(link.href);
child.properties = relation.properties[relation.children[index]];
return child;
});
}
else if (relation_1.RelationBase.isParentToOneChildRelation(relation)) {
if (relation.child) {
const link = yield this._client.linkHelper.entityToLinkAsync(relation.child);
resource.child = new entity_link_1.EntityLink(link.href);
resource.child.properties = relation.properties[relation.child];
}
}
else {
throw new not_supported_error_1.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_1.default.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_1.default.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 = relation_resource_1.RelationResource.merge(existing, mappedRelation);
dict[relation.name] = merged;
}
else {
dict[relation.name] = mappedRelation;
}
}
return dict;
});
}
}
exports.RelationMapper = RelationMapper;
//# sourceMappingURL=relation-mapper.js.map