@enonic/mock-xp
Version:
Mock Enonic XP API JavaScript Library
414 lines (413 loc) • 19 kB
JavaScript
"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;