UNPKG

@enonic/mock-xp

Version:

Mock Enonic XP API JavaScript Library

414 lines (413 loc) 19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ContentConnection = void 0; var tslib_1 = require("tslib"); var js_utils_1 = require("@enonic/js-utils"); var node_forge_1 = require("node-forge"); var probe_image_size_1 = require("probe-image-size"); var constants_1 = require("./node/constants"); var NodeAlreadyExistAtPathException_1 = require("./node/NodeAlreadyExistAtPathException"); var NodeNotFoundException_1 = require("./node/NodeNotFoundException"); var CHILD_ORDER_DEFAULT = 'displayname ASC'; var USER_DEFAULT = 'user:system:su'; var ContentConnection = (function () { function ContentConnection(_a) { var branch = _a.branch; this.branch = branch; this.log = branch.repo.server.log; this.vol = branch.repo.server.vol; if (!this.branch.existsNode('/content')) { this.branch.createNode({ _childOrder: CHILD_ORDER_DEFAULT, _indexConfig: constants_1.INDEX_CONFIG_DEFAULT, _inheritsPermissions: false, _name: 'content', _parentPath: '/', _permissions: constants_1.PERMISSIONS_DEFAULT, displayName: 'Content', type: 'base:folder', valid: false, }); } } ContentConnection.prototype.contentToNode = function (_a) { var _b; var content = _a.content, _c = _a.mode, mode = _c === void 0 ? 'create' : _c; var name = content.name, parentPath = content.parentPath, displayName = content.displayName, contentType = content.contentType, language = content.language, childOrder = content.childOrder, data = content.data, type = content.type, x = content.x; var node = { createdTime: new Date().toISOString(), creator: USER_DEFAULT, data: data, owner: USER_DEFAULT, type: contentType || type, x: x }; if (mode === 'create') { node['_parentPath'] = "/content".concat(parentPath); } else if (mode === 'modify') { if (!((_b = node._path) === null || _b === void 0 ? void 0 : _b.startsWith('/content'))) { node._path = "/content".concat(node._path); } node['modifiedTime'] = new Date().toISOString(); node['modifier'] = USER_DEFAULT; } if (childOrder) { node._childOrder = childOrder; } if (displayName) { node['displayName'] = displayName; } if (language) { node['language'] = language; } if (name) { node._name = name; } if (mode === 'create') { return node; } return node; }; ContentConnection.prototype.create = function (params) { var createNodeParams = this.contentToNode({ content: params, mode: 'create' }); var createdNode = this.branch.createNode(createNodeParams); return this.nodeToContent({ node: createdNode }); }; ContentConnection.prototype.createMedia = function (params) { var fileBuffer = params.data, _a = params.focalX, focalX = _a === void 0 ? 0.5 : _a, _b = params.focalY, focalY = _b === void 0 ? 0.5 : _b, mimeType = params.mimeType, name = params.name, _c = params.parentPath, parentPath = _c === void 0 ? '/' : _c; var probeRes = (0, probe_image_size_1.sync)(fileBuffer); var _d = probeRes || {}, _e = _d.height, height = _e === void 0 ? 0 : _e, _f = _d.width, width = _f === void 0 ? 0 : _f; var data = fileBuffer.toString(); var sha512HexDigest = node_forge_1.sha512.create().update(data).digest().toHex(); var filePath = "/".concat(sha512HexDigest); this.vol.writeFileSync(filePath, data); var stats = this.vol.statSync(filePath); var size = stats.size; var nameParts = name.split('.'); nameParts.pop(); var displayName = nameParts.join('.'); var createdNode = this.branch.createNode({ _childOrder: CHILD_ORDER_DEFAULT, _indexConfig: constants_1.INDEX_CONFIG_DEFAULT, _inheritsPermissions: true, _name: name, _parentPath: "/content".concat(parentPath), _permissions: constants_1.PERMISSIONS_DEFAULT, _nodeType: 'content', attachment: { binary: name, label: 'source', mimeType: mimeType, name: name, size: size, sha512: sha512HexDigest }, creator: USER_DEFAULT, createdTime: new Date().toISOString(), data: { artist: '', caption: '', copyright: '', media: { attachment: name, focalPoint: { x: focalX, y: focalY } }, tags: '' }, displayName: displayName, type: 'media:image', owner: USER_DEFAULT, valid: true, x: { media: { imageInfo: { imageHeight: height, imageWidth: width, contentType: mimeType, pixelSize: width * height, byteSize: size } } } }); var createdContent = this.nodeToContent({ node: createdNode }); return createdContent; }; ContentConnection.prototype.delete = function (params) { var key = params.key; if (key.startsWith('/')) { key = "/content".concat(key); } var _a = tslib_1.__read(this.branch.deleteNode(key), 1), deletedId = _a[0]; return !!deletedId; }; ContentConnection.prototype.exists = function (params) { var key = params.key; if (key.startsWith('/')) { key = "/content".concat(key); } var exists = this.branch.existsNode(key); return exists; }; ContentConnection.prototype.get = function (params) { var key = params.key; if (key.startsWith('/')) { key = "/content".concat(key); } var node = this.branch.getNode(key); if (!node) { return null; } return this.nodeToContent({ node: node }); }; ContentConnection.prototype.getAttachmentStream = function (params) { var key = params.key; if (key.startsWith('/')) { key = "/content".concat(key); } var paramName = params.name; var node = this.branch.getNode(key); if (!node) { return null; } var _a = node.attachment, _b = _a === void 0 ? {} : _a, attachmentName = _b.name, sha512 = _b.sha512; if (attachmentName !== paramName) { this.log.warning('ContentConnection getAttachmentStream content has no attachment named:%s', paramName); return null; } if (!sha512) { this.log.warning('ContentConnection getAttachmentStream unable to find sha512 for attachment named:%s', paramName); return null; } return this.vol.readFileSync("/".concat(sha512)); }; ContentConnection.prototype.modify = function (params) { var contentIdOrPath = params.key, editor = params.editor; var content = this.get({ key: contentIdOrPath }); if (!content) { throw new Error("modify: Content not found for key: ".concat(contentIdOrPath)); } var contentToBeModified = editor(content); var nodeToBeModified = this.contentToNode({ content: contentToBeModified, mode: 'modify' }); var rootProps = Object.keys(nodeToBeModified).filter(function (key) { return !key.startsWith('_') && key !== 'createdTime' && key !== 'creator'; }); var nodeKey = contentIdOrPath.startsWith('/') ? "/content".concat(contentIdOrPath) : contentIdOrPath; var modifiedNode = this.branch.modifyNode({ key: nodeKey, editor: function (existingNode) { for (var i = 0; i < rootProps.length; i++) { var prop = rootProps[i]; existingNode[prop] = nodeToBeModified[prop]; } return existingNode; } }); var modifiedContent = this.nodeToContent({ node: modifiedNode }); return modifiedContent; }; ContentConnection.prototype.move = function (params) { var source = params.source, target = params.target; if (!this.exists({ key: source })) { throw new Error("move: Source content not found! key: ".concat(source)); } ; var nodeSource = source.startsWith('/') ? "/content".concat(source) : source; var nodeTarget = target.startsWith('/') ? "/content".concat(target) : target; var movedNode; try { movedNode = this.branch.moveNode({ source: nodeSource, target: nodeTarget }); } catch (e) { if (e instanceof NodeNotFoundException_1.NodeNotFoundException) { throw new Error("Cannot move content with source ".concat(source, " to target ").concat(target, ": Parent of target not found!")); } if (e instanceof NodeAlreadyExistAtPathException_1.NodeAlreadyExistAtPathException) { throw new Error("Cannot move content with source ".concat(source, " to target ").concat(target, ": Content already exists at target!")); } } var modifiedContent = this.modify({ key: movedNode._id, editor: function (n) { return n; } }); return modifiedContent; }; ContentConnection.prototype.nodeToContent = function (_a) { var _b, _c, _d, _e; var node = _a.node; var _childOrder = node._childOrder, _id = node._id, _name = node._name, _path = node._path, components = node.components, creator = node.creator, createdTime = node.createdTime, data = node.data, _f = node.displayName, displayName = _f === void 0 ? _name : _f, language = node.language, modifier = node.modifier, modifiedTime = node.modifiedTime, owner = node.owner, type = node.type, _g = node.valid, valid = _g === void 0 ? true : _g, _h = node.x, x = _h === void 0 ? {} : _h; var content = { _id: _id, _name: _name, _path: _path.replace(/^\/content/, ''), attachments: {}, childOrder: _childOrder, creator: creator, createdTime: createdTime, data: data, displayName: displayName, hasChildren: true, owner: owner, publish: {}, type: type, valid: valid, x: x }; if (language) { content.language = language; } if (modifier) { content.modifier = modifier; } if (modifiedTime) { content.modifiedTime = modifiedTime; } if (components) { var fragmentOrPage = {}; for (var i = 0; i < components.length; i++) { var component = components[i]; var path = component.path, type_1 = component.type; if (type_1 === 'page' && path === '/') { var _j = component.page, config = _j.config, descriptor = _j.descriptor; var _k = tslib_1.__read(descriptor.split(':'), 2), app_1 = _k[0], componentName = _k[1]; var dashedApp = app_1.replace(/\./g, '-'); (0, js_utils_1.setIn)(fragmentOrPage, 'descriptor', descriptor); (0, js_utils_1.setIn)(fragmentOrPage, 'path', path); if ((_b = config === null || config === void 0 ? void 0 : config[dashedApp]) === null || _b === void 0 ? void 0 : _b[componentName]) { (0, js_utils_1.setIn)(fragmentOrPage, 'config', (_c = config === null || config === void 0 ? void 0 : config[dashedApp]) === null || _c === void 0 ? void 0 : _c[componentName]); } (0, js_utils_1.setIn)(fragmentOrPage, 'type', type_1); (0, js_utils_1.setIn)(fragmentOrPage, 'regions', {}); content.page = fragmentOrPage; } else { var pathParts = path.split('/'); pathParts.shift(); var pageRegionName = pathParts[0]; if (!(0, js_utils_1.getIn)(fragmentOrPage.regions, pageRegionName)) { (0, js_utils_1.setIn)(fragmentOrPage.regions, pageRegionName, { components: [], name: pageRegionName, }); } var pageRegion = fragmentOrPage.regions[pageRegionName]; if (type_1 === 'layout') { var _l = component.layout, config = _l.config, descriptor = _l.descriptor; var _m = tslib_1.__read(descriptor.split(':'), 2), app_2 = _m[0], componentName = _m[1]; var dashedApp = app_2.replace(/\./g, '-'); var layout = { config: (_d = config === null || config === void 0 ? void 0 : config[dashedApp]) === null || _d === void 0 ? void 0 : _d[componentName], descriptor: descriptor, path: path, regions: {}, type: type_1 }; pageRegion.components.push(layout); } else if (type_1 === 'part') { var _o = component.part, config = _o.config, descriptor = _o.descriptor; var _p = tslib_1.__read(descriptor.split(':'), 2), app_3 = _p[0], componentName = _p[1]; var dashedApp = app_3.replace(/\./g, '-'); var part = { config: (_e = config === null || config === void 0 ? void 0 : config[dashedApp]) === null || _e === void 0 ? void 0 : _e[componentName], descriptor: descriptor, path: path, type: type_1 }; if (pathParts.length === 2) { pageRegion.components.push(part); } else if (pathParts.length === 4) { var pageComponentRegionIndex = pathParts[1]; var layoutComponent = pageRegion.components[pageComponentRegionIndex]; var layoutRegionName = pathParts[2]; if (!layoutComponent.regions[layoutRegionName]) { layoutComponent.regions[layoutRegionName] = { components: [], name: layoutRegionName, }; } ; layoutComponent.regions[layoutRegionName].components.push(part); } } } } } return content; }; ContentConnection.prototype.publish = function (params) { var keys = params.keys; var branchId = this.branch.getBranchId(); if (branchId !== 'draft') { throw new Error("ContentConnection publish only allowed from the draft branch, got:".concat(branchId)); } var masterBranch = this.branch.getRepo().getBranch('master'); var contentMasterConnection = new ContentConnection({ branch: masterBranch }); var res = { deletedContents: [], failedContents: [], pushedContents: [], }; contentKeysLoop: for (var i = 0; i < keys.length; i++) { var contentKey = keys[i]; var nodeKey = contentKey.startsWith('/') ? "/content".concat(contentKey) : contentKey; var existsOnDraft = this.exists({ key: contentKey }); if (existsOnDraft) { var nodeOnDraft = this.branch.getNode(nodeKey); var nodeId = nodeOnDraft._id; var existsOnMaster_1 = contentMasterConnection.exists({ key: nodeId }); if (existsOnMaster_1) { var overriddenNode = masterBranch._overwriteNode({ node: nodeOnDraft }); if (overriddenNode) { this.log.debug("ContentConnection publish: Modified content with id %s on the master branch!", nodeId); res.pushedContents.push(contentKey); } continue contentKeysLoop; } var pathParts = nodeOnDraft._path.split('/'); pathParts.pop(); nodeOnDraft['_parentPath'] = pathParts.join('/'); var createdNode = masterBranch._createNodeInternal(nodeOnDraft); if (createdNode) { this.log.debug("ContentConnection publish: Created content with key %s on the master branch!", contentKey); res.pushedContents.push(contentKey); } continue contentKeysLoop; } var existsOnMaster = contentMasterConnection.exists({ key: contentKey }); if (existsOnMaster) { if (contentMasterConnection.delete({ key: contentKey })) { this.log.debug("ContentConnection publish: Deleted content with key %s from the master branch!", contentKey); res.deletedContents.push(contentKey); continue contentKeysLoop; } else { this.log.error("ContentConnection publish: Failed to delete content with key %s from the master branch!", contentKey); res.failedContents.push(contentKey); continue contentKeysLoop; } } this.log.error("ContentConnection publish: Content with key %s doesn't exist on the draft nor the master branch!", contentKey); res.failedContents.push(contentKey); } return res; }; return ContentConnection; }()); exports.ContentConnection = ContentConnection;