UNPKG

@sitecore/sc-contenthub-webclient-sdk

Version:

Sitecore Content Hub WebClient SDK.

236 lines 13.4 kB
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