UNPKG

@sitecore/sc-contenthub-webclient-sdk

Version:

Sitecore Content Hub WebClient SDK.

243 lines 14.6 kB
"use strict"; 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