@rnaga/wp-node
Version:
👉 **[View Full Documentation at rnaga.github.io/wp-node →](https://rnaga.github.io/wp-node/)**
279 lines (278 loc) • 12.1 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RevisionTrx = void 0;
const common_1 = require("../common");
const config_1 = require("../config");
const components_1 = require("../core/components");
const current_1 = require("../core/current");
const meta_util_1 = require("../core/utils/meta.util");
const post_util_1 = require("../core/utils/post.util");
const revision_util_1 = require("../core/utils/revision.util");
const vars_1 = require("../core/vars");
const database_1 = __importDefault(require("../database"));
const component_1 = require("../decorators/component");
const meta_trx_1 = require("./meta.trx");
const post_trx_1 = require("./post.trx");
const trx_1 = require("./trx");
const val = __importStar(require("../validators"));
const diff_1 = require("../common/diff");
let RevisionTrx = class RevisionTrx extends trx_1.Trx {
database;
config;
components;
postUtil;
revisionUtil;
vars;
constructor(database, config, components, postUtil, revisionUtil, vars) {
super(components);
this.database = database;
this.config = config;
this.components = components;
this.postUtil = postUtil;
this.revisionUtil = revisionUtil;
this.vars = vars;
}
// _wp_put_post_revision
async upsert(post, options) {
const { autoSave = false, meta = undefined } = options ?? {};
// start _wp_put_post_revision
const postInput = common_1.formatting.slash(this.revisionUtil.convertToData(post, autoSave));
const postTrx = this.components.get(post_trx_1.PostTrx);
const revisionId = await postTrx.upsert(postInput);
await this.syncMeta(post.ID, revisionId, { meta });
return revisionId;
}
// wp_save_revisioned_meta_fields
// wp_restore_post_revision_meta
async syncMeta(srcPostId, dstPostId, options) {
const { excludekeys = [] } = options ?? {};
const metaTrx = this.components.get(meta_trx_1.MetaTrx);
const metaUtil = this.components.get(meta_util_1.MetaUtil);
const postUtil = this.components.get(post_util_1.PostUtil);
const srcPost = await postUtil.get(srcPostId);
const srcMetas = { ...(await srcPost.meta.props()), ...options?.meta };
if (Object.keys(srcMetas).length === 0) {
return;
}
const syncedMetaKeys = [];
for (const [key, value] of Object.entries(srcMetas)) {
// Skip protected meta keys or excluded keys passed in options
if (metaUtil.isProtected(key, "post") || excludekeys.includes(key)) {
syncedMetaKeys.push(key);
continue;
}
await metaTrx.upsert("post", dstPostId, key, value, {
serialize: typeof value === "object",
});
syncedMetaKeys.push(key);
}
// Remove meta keys that are not in the source post
const dstPost = await postUtil.get(dstPostId);
const dstMetas = await dstPost.meta.props();
for (const key in dstMetas) {
if (syncedMetaKeys.includes(key) || metaUtil.isProtected(key, "post")) {
continue;
}
await metaTrx.remove("post", {
objectId: dstPostId,
key,
});
}
}
// wp_save_post_revision
async save(postId) {
if (this.vars.DOING_AUTOSAVE) {
return;
}
const post = await this.postUtil.get(postId);
if (!post.props) {
return;
}
const postType = this.postUtil.getTypeObject(post.props.post_type);
if (!postType?.supports.includes("revisions")) {
return;
}
if ("auto-draft" === post.props.post_type) {
return;
}
/*
* Compare the proposed update with the last stored revision verifying that
* they are different, unless a plugin tells us to always save regardless.
* If no previous revisions, save one.
*/
let revisions = await this.revisionUtil.getList(postId);
if (revisions.length > 0) {
// Grab the latest revision, but not an autosave.
const latestRevision = revisions.filter((revision) => revision.post_name.includes(`${revision.post_parent}-revision`))[0] ?? {};
const fields = Object.keys(revision_util_1.RevisionUtil.revisionFields);
const hasChanged = fields.filter((column) => post.props &&
"string" === typeof post.props[column] &&
"string" === typeof latestRevision[column] &&
common_1.formatting.normalizeWhitespace(post.props[column]) !==
common_1.formatting.normalizeWhitespace(latestRevision[column])).length > 0;
if (!hasChanged) {
return;
}
}
// start _wp_put_post_revision
const resultPostId = await this.upsert(post.props);
/*
* If a limit for the number of revisions to keep has been set,
* delete the oldest ones.
*/
const WP_POST_REVISIONS = this.config.config.constants.WP_POST_REVISIONS;
if (WP_POST_REVISIONS < 0) {
return resultPostId;
}
revisions = await this.revisionUtil.getList(postId, (query) => {
const { column } = query.alias;
query.builder.clear("order").orderBy(column("posts", "ID"), "asc");
});
const deleteCount = revisions.length - WP_POST_REVISIONS;
if (deleteCount < 1) {
return resultPostId;
}
const sliceRevisions = revisions.slice(0, deleteCount);
for (const revision of sliceRevisions) {
if (revision.post_name.includes("autosave")) {
continue;
}
await this.remove(revision.ID);
}
return resultPostId;
}
// wp_restore_post_revision
async restore(revisionOrId, options) {
const fields = options?.fields ??
Object.keys(revision_util_1.RevisionUtil.revisionFields);
if (!fields) {
return false;
}
const post = typeof revisionOrId == "number"
? await this.postUtil.get(revisionOrId)
: revisionOrId;
if (!post.props || !post.props.post_parent) {
return post;
}
const parentId = post.props.post_parent;
const postUpsert = fields
.map((field) => ({
[field]: common_1.formatting.slash(post.props ? post.props[field] : undefined),
}))
.reduce((a, b) => ({ ...a, ...b }), {});
postUpsert.ID = parentId;
const postTrx = this.components.get(post_trx_1.PostTrx);
const postId = await postTrx.upsert(postUpsert);
const current = this.components.get(current_1.Current);
const metaTrx = this.components.get(meta_trx_1.MetaTrx);
await metaTrx.upsert("post", postId, "_edit_last", current.user?.props?.ID ?? 0);
await this.syncMeta(post.props.ID, postId);
return postId;
}
// wp_delete_post_revision
async remove(postOrId) {
const post = typeof postOrId == "number"
? await this.postUtil.get(postOrId)
: postOrId;
if (!post.props) {
return post;
}
const postTrx = this.components.get(post_trx_1.PostTrx);
return await postTrx.remove(post.props.ID);
}
// class-wp-rest-autosaves-controller.php create_post_autosave
async autosave(input, options) {
const current = this.components.get(current_1.Current);
const { userId = current.user?.props?.ID } = options ?? {};
if (!userId) {
// No user ID is provided. Skip autosave.
return undefined;
}
const data = val.database.wpPosts.parse(input);
const autosaveMeta = val.trx.postUpsert.shape.meta_input.parse(input.meta_input);
const autosavePost = this.revisionUtil.convertToData(data, true);
const post = await this.postUtil.get(data.ID);
const postId = post.props?.ID;
if (!postId) {
// Post not found. Skip autosave.
return undefined;
}
const oldAutosave = await this.revisionUtil.getAutosave(postId, userId);
const diffData = (0, diff_1.diffObject)(autosavePost, post.props);
const diffDataKeys = Object.keys(revision_util_1.RevisionUtil.revisionFields).filter((field) => diffData?.[field]);
const meta = await post.meta.props();
const diffMetaKeys = Object.keys((0, diff_1.diffObject)(autosaveMeta, meta));
if (diffDataKeys.length === 0 &&
diffMetaKeys.length === 0 &&
oldAutosave?.props) {
// No changes. Skip autosave.
return oldAutosave.props.ID;
}
// start _wp_put_post_revision
const postInput = common_1.formatting.slash(this.revisionUtil.convertToData(data, true));
postInput.post_author = userId;
// Store one autosave per author. If there is already an autosave, overwrite it.
if (oldAutosave?.props) {
postInput.ID = oldAutosave.props.ID;
}
const postTrx = this.components.get(post_trx_1.PostTrx);
const revisionId = await postTrx.upsert(postInput);
await this.syncMeta(postId, revisionId, { meta });
return revisionId;
}
};
exports.RevisionTrx = RevisionTrx;
exports.RevisionTrx = RevisionTrx = __decorate([
(0, component_1.transactions)(),
__metadata("design:paramtypes", [database_1.default,
config_1.Config,
components_1.Components,
post_util_1.PostUtil,
revision_util_1.RevisionUtil,
vars_1.Vars])
], RevisionTrx);