Last active
December 12, 2017 12:52
-
-
Save varunchopra/3dbf3585a2f3154b59ea302615d51e10 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var maps = {}; | |
function extend(a, b) { | |
for (var p in b) { | |
a[p] = b[p]; | |
} | |
return a; | |
} | |
function createFieldMaps(renames, toFns, fromFns) { | |
var to = extend({}, renames), | |
from = {}; | |
Object.keys(renames).forEach(function(key) { | |
from[renames[key]] = key; | |
}); | |
return { | |
renames: renames, | |
to: extend(to, toFns), | |
from: extend(from, fromFns) | |
}; | |
} | |
function mapFields(data, map) { | |
var field, value, mappedField, | |
ret = {}; | |
for (field in data) { | |
value = data[field]; | |
mappedField = map[field]; | |
// no map -> delete | |
if (!mappedField) { | |
continue; | |
// string -> change field name | |
} else if (typeof mappedField === "string") { | |
ret[mappedField] = value; | |
// function -> merge result | |
} else { | |
extend(ret, mappedField(value)); | |
} | |
} | |
return ret; | |
} | |
maps.labels = createFieldMaps({ | |
addNewItem: "add_new_item", | |
addOrRemoveItems: "add_or_remove_items", | |
allItems: "all_items", | |
chooseFromMostUsed: "choose_from_most_used", | |
editItem: "edit_item", | |
menuName: "menu_name", | |
name: "name", | |
nameAdminBar: "name_admin_bar", | |
newItemName: "new_item_name", | |
parentItem: "parent_item", | |
parentItemColon: "parent_item_colon", | |
popularItems: "popular_items", | |
searchItems: "search_items", | |
separateItemsWithCommas: "separate_items_with_commas", | |
singularName: "singular_name", | |
updateItem: "update_item", | |
viewItem: "view_item" | |
}); | |
maps.post = createFieldMaps({ | |
author: /* int */ "post_author", | |
commentStatus: /* string */ "comment_status", | |
content: /* string */ "post_content", | |
customFields: /* array */ "custom_fields", | |
date: /* datetime */ "post_date", | |
excerpt: /* string */ "post_excerpt", | |
format: /* string */ "post_format", | |
id: /* string */ "post_id", | |
/* readonly */ | |
link: /* string */ "link" /* readonly */ , | |
modified: /* datetime */ "post_modified", | |
menuOrder: /* int */ "menu_order", | |
name: /* string */ "post_name", | |
pageTemplate: /* string */ "page_template", | |
parent: /* int */ "post_parent", | |
password: /* string */ "post_password", | |
pingStatus: /* string */ "ping_status", | |
status: /* string */ "post_status", | |
sticky: /* bool */ "sticky", | |
terms: /* struct */ "terms" /* array */ , | |
termNames: /* struct */ "terms_names", | |
thumbnail: /* int */ "post_thumbnail", | |
title: /* string */ "post_title", | |
type: /* string */ "post_type" | |
}, {}, { | |
post_date_gmt: /* datetime */ function(date) { | |
return { | |
date: new Date(date) | |
}; | |
}, | |
post_modified_gmt: /* datetime */ function(date) { | |
return { | |
modified: new Date(date) | |
}; | |
} | |
}); | |
maps.postType = createFieldMaps({ | |
_builtin: /* bool */ "_builtin", | |
cap: /* struct */ "cap", | |
capabilityType: /* string */ "capability_type", | |
description: /* string */ "description", | |
_editLink: /* string */ "_edit_link", | |
excludeFromSearch: /* bool */ "exclude_from_search", | |
hasArchive: /* bool */ "has_archive", | |
hierarchical: /* bool */ "hierarchical", | |
label: /* string */ "label", | |
labels: /* struct */ "labels", | |
mapMetaCap: /* bool */ "map_meta_cap", | |
menuIcon: /* string */ "menu_icon", | |
menuPosition: /* int */ "menu_position", | |
name: /* string */ "name", | |
"public": /* bool */ "public", | |
publiclyQuerably: /* bool */ "publicly_queryable", | |
queryVar: /* mixed */ "query_var", | |
rewrite: /* mixed */ "rewrite", | |
showInAdminBar: /* bool */ "show_in_admin_bar", | |
showInMenu: /* bool */ "show_in_menu", | |
showInNavMenus: /* bool */ "show_in_nav_menus", | |
showUi: /* bool */ "show_ui", | |
supports: /* array */ "supports", | |
taxonomies: /* array */ "taxonomies" | |
}, {}, { | |
cap: function(cap) { | |
return { | |
cap: mapFields(cap, maps.postTypeCap.from) | |
}; | |
}, | |
labels: function(labels) { | |
return { | |
labels: mapFields(labels, maps.labels.from) | |
}; | |
} | |
}); | |
maps.postTypeCap = createFieldMaps({ | |
deleteOthersPosts: /* string */ "delete_others_posts", | |
deletePost: /* string */ "delete_post", | |
deletePosts: /* string */ "delete_posts", | |
deletePrivatePosts: /* string */ "delete_private_posts", | |
deletePublishedPosts: /* string */ "delete_published_posts", | |
editOthersPosts: /* string */ "edit_others_posts", | |
editPost: /* string */ "edit_post", | |
editPosts: /* string */ "edit_posts", | |
editPrivatePosts: /* string */ "edit_private_posts", | |
editPublishedPosts: /* string */ "edit_published_posts", | |
publishPosts: /* string */ "publish_posts", | |
read: /* string */ "read", | |
readPost: /* sring */ "read_post", | |
readPrivatePosts: /* string */ "read_private_posts" | |
}); | |
maps.taxonomy = createFieldMaps({ | |
cap: /* struct */ "cap", | |
hierarchical: /* bool */ "hierarchical", | |
name: /* string */ "name", | |
label: /* string */ "label", | |
labels: /* struct */ "labels", | |
objectType: /* array */ "object_type", | |
"public": /* bool */ "public", | |
queryVar: /* string */ "query_var", | |
rewrite: /* struct */ "rewrite", | |
showInNavMenus: /* bool */ "show_in_nav_menus", | |
showTagCloud: /* bool */ "show_tagcloud", | |
showUi: /* bool */ "show_ui" | |
}, {}, { | |
cap: function(cap) { | |
return { | |
cap: mapFields(cap, maps.taxonomyCap.from) | |
}; | |
}, | |
labels: function(labels) { | |
return { | |
labels: mapFields(labels, maps.labels.from) | |
}; | |
} | |
}); | |
maps.taxonomyCap = createFieldMaps({ | |
assignTerms: /* string */ "assign_terms", | |
deleteTerms: /* string */ "delete_terms", | |
editTerms: /* string */ "edit_terms", | |
manageTerms: /* string */ "manage_terms" | |
}); | |
maps.term = createFieldMaps({ | |
count: /* int */ "count", | |
/* readonly */ | |
description: /* string */ "description", | |
name: /* string */ "name", | |
parent: /* string */ "parent", | |
slug: /* string */ "slug", | |
taxonomy: /* string */ "taxonomy", | |
termId: /* string */ "term_id", | |
/* readonly */ | |
termTaxonomyId: /* string */ "term_taxonomy_id" /* readonly */ | |
}); | |
maps.file = createFieldMaps({ | |
name: /* string */ "name", | |
type: /* string */ "type", | |
bits: /* string */ "bits", | |
overwrite: /* boolean */ "overwrite", | |
postId: /* int */ "post_id" | |
}); | |
maps.media = createFieldMaps({ | |
attachmentId: /* string */ "attachment_id", | |
/* readonly */ | |
caption: /* string */ "caption", | |
description: /* string */ "description", | |
link: /* string */ "link", | |
parent: /* int */ "parent", | |
thumbnail: /* string */ "thumbnail", | |
title: /* string */ "title", | |
type: /* string */ "type" | |
}, {}, { | |
date_created_gmt: /* datetime */ function(date) { | |
return { | |
date: new Date(date) | |
}; | |
}, | |
metadata: /* struct */ function(data) { | |
return { | |
metadata: mapFields(data, maps.mediaItemMetadata.from) | |
}; | |
} | |
}); | |
maps.mediaItemMetadata = createFieldMaps({ | |
file: /* string */ "file", | |
height: /* int */ "height", | |
sizes: /* struct */ "sizes", | |
width: /* int */ "width" | |
}, {}, { | |
sizes: /* struct */ function(size) { | |
var keys = Object.keys(size), | |
results = {}; | |
// Loop through the available sizes and map the fields | |
keys.forEach(function(key, i) { | |
results[keys[i]] = mapFields(size[keys[i]], maps.mediaItemSize.from); | |
}); | |
return { | |
sizes: results | |
}; | |
}, | |
image_meta: /* struct */ function(data) { | |
return { | |
imageMeta: mapFields(data, maps.postThumbnailImageMeta.from) | |
}; | |
} | |
}); | |
maps.mediaItemSize = createFieldMaps({ | |
file: /* string */ "file", | |
height: /* string */ "height", | |
mimeType: /* string */ "mime-type", | |
width: /* string */ "width" | |
}); | |
maps.postThumbnailImageMeta = createFieldMaps({ | |
aperture: /* int */ "aperture", | |
camera: /* string */ "camera", | |
caption: /* string */ "caption", | |
copyright: /* string */ "copyright", | |
createdTimestamp: /* int */ "created_timestamp", | |
credit: /* string */ "credit", | |
focalLength: /* int */ "focal_length", | |
iso: /* int */ "iso", | |
keywords: /* array */ "keywords", | |
orientation: /* string */ "orientation", | |
shutterSpeed: /* int */ "shutter_speed", | |
title: /* string */ "title" | |
}); | |
module.exports = { | |
to: function(data, type) { | |
return mapFields(data, maps[type].to); | |
}, | |
from: function(data, type) { | |
return mapFields(data, maps[type].from); | |
}, | |
array: function(data, type) { | |
var map = maps[type].renames; | |
return data.map(function(field) { | |
return map[field]; | |
}); | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var url = require("url"), | |
xmlrpc = require("xmlrpc"), | |
fieldMap = require("./fields"); | |
// http://codex.wordpress.org/XML-RPC_Support | |
// http://codex.wordpress.org/XML-RPC_WordPress_API | |
function extend(a, b) { | |
for (var p in b) { | |
a[p] = b[p]; | |
} | |
return a; | |
} | |
function parseArguments(args) { | |
return [].slice.call(args, 1) | |
// Remove null arguments | |
// Null values only exist for optional fields. As of WordPress 4.4, | |
// null is no longer treated the same as omitting the value. To | |
// compensate for this, we just drop the argument before calling | |
// into WordPress. See #25. | |
.filter(function(value) { | |
return value !== null; | |
}); | |
} | |
function Client(settings) { | |
["url", "username", "password"].forEach(function(prop) { | |
if (!settings.hasOwnProperty(prop)) { | |
throw new Error("Missing required setting: " + prop); | |
} | |
}); | |
var parsedUrl = Client.parseUrl(settings.url); | |
this.rpc = xmlrpc[parsedUrl.secure ? "createSecureClient" : "createClient"]({ | |
host: settings.host || parsedUrl.host, | |
port: parsedUrl.port, | |
path: parsedUrl.path, | |
rejectUnauthorized: settings.rejectUnauthorized !== undefined ? settings.rejectUnauthorized : true, | |
// Always set Host header in case we're pointing to a different server | |
// via settings.host | |
headers: { | |
Host: parsedUrl.host | |
}, | |
basic_auth: !settings.basicAuth ? null : { | |
user: settings.basicAuth.username, | |
pass: settings.basicAuth.password | |
} | |
}); | |
this.blogId = settings.blogId || 0; | |
this.username = settings.username; | |
this.password = settings.password; | |
} | |
Client.parseUrl = function(wpUrl) { | |
var urlParts, secure; | |
// allow URLs without a protocol | |
if (!(/\w+:\/\//.test(wpUrl))) { | |
wpUrl = "http://" + wpUrl; | |
} | |
urlParts = url.parse(wpUrl); | |
secure = urlParts.protocol === "https:"; | |
return { | |
host: urlParts.hostname, | |
port: urlParts.port || (secure ? 443 : 80), | |
path: urlParts.path.replace(/\/+$/, "") + "/xmlrpc.php", | |
secure: secure | |
}; | |
}; | |
extend(Client.prototype, { | |
call: function(method) { | |
var args = parseArguments(arguments), | |
fn = args.pop(); | |
if (typeof fn !== "function") { | |
args.push(fn); | |
fn = null; | |
} | |
this.rpc.methodCall(method, args, function(error, data) { | |
if (!error) { | |
return fn(null, data); | |
} | |
if (error.code === "ENOTFOUND" && error.syscall === "getaddrinfo") { | |
error.message = "Unable to connect to WordPress."; | |
} else if (error.message === "Unknown XML-RPC tag 'TITLE'") { | |
var additional = error.res.statusCode; | |
if (error.res.statusMessage) { | |
additional += "; " + error.res.statusMessage; | |
} | |
error.message = "(" + additional + ") " + error.message; | |
} | |
fn(error); | |
}); | |
}, | |
authenticatedCall: function() { | |
var args = [].slice.call(arguments); | |
args.splice(1, 0, this.blogId, this.username, this.password); | |
this.call.apply(this, args); | |
}, | |
listMethods: function(fn) { | |
this.call("system.listMethods", fn); | |
} | |
}); | |
extend(Client.prototype, { | |
getPost: function(id, fields, fn) { | |
if (typeof fields === "function") { | |
fn = fields; | |
fields = null; | |
} | |
if (fields) { | |
fields = fieldMap.array(fields, "post"); | |
} | |
this.authenticatedCall("wp.getPost", id, fields, function(error, post) { | |
if (error) { | |
return fn(error); | |
} | |
fn(null, fieldMap.from(post, "post")); | |
}); | |
}, | |
getPosts: function(filter, fields, fn) { | |
if (typeof filter === "function") { | |
fn = filter; | |
fields = null; | |
filter = {}; | |
} | |
if (typeof fields === "function") { | |
fn = fields; | |
fields = null; | |
} | |
if (filter.type) { | |
filter.post_type = filter.type; | |
delete filter.type; | |
} | |
if (filter.status) { | |
filter.post_status = filter.status; | |
delete filter.status; | |
} | |
if (filter.orderby) { | |
filter.orderby = fieldMap.array([filter.orderby], "post")[0]; | |
} | |
if (fields) { | |
fields = fieldMap.array(fields, "post"); | |
} | |
this.authenticatedCall("wp.getPosts", filter, fields, function(error, posts) { | |
if (error) { | |
return fn(error); | |
} | |
fn(null, posts.map(function(post) { | |
return fieldMap.from(post, "post"); | |
})); | |
}); | |
}, | |
newPost: function(data, fn) { | |
this.authenticatedCall("wp.newPost", fieldMap.to(data, "post"), fn); | |
}, | |
// to remove a term, just set the terms and leave out the id that you want to remove | |
// to remove a custom field, pass the id with no key or value | |
editPost: function(id, data, fn) { | |
this.authenticatedCall("wp.editPost", id, fieldMap.to(data, "post"), fn); | |
}, | |
deletePost: function(id, fn) { | |
this.authenticatedCall("wp.deletePost", id, fn); | |
}, | |
getPostType: function(name, fields, fn) { | |
if (typeof fields === "function") { | |
fn = fields; | |
fields = null; | |
} | |
if (fields) { | |
fields = fieldMap.array(fields, "postType"); | |
} | |
this.authenticatedCall("wp.getPostType", name, fields, function(error, postType) { | |
if (error) { | |
return fn(error); | |
} | |
fn(null, fieldMap.from(postType, "postType")); | |
}); | |
}, | |
getPostTypes: function(filter, fields, fn) { | |
if (typeof filter === "function") { | |
fn = filter; | |
fields = null; | |
filter = {}; | |
} | |
if (typeof fields === "function") { | |
fn = fields; | |
fields = null; | |
} | |
if (Array.isArray(filter)) { | |
fields = filter; | |
filter = {}; | |
} | |
if (fields) { | |
fields = fieldMap.array(fields, "postType"); | |
} | |
this.authenticatedCall("wp.getPostTypes", filter, fields, function(error, postTypes) { | |
if (error) { | |
return fn(error); | |
} | |
Object.keys(postTypes).forEach(function(postType) { | |
postTypes[postType] = fieldMap.from(postTypes[postType], "postType"); | |
}); | |
fn(null, postTypes); | |
}); | |
} | |
}); | |
extend(Client.prototype, { | |
getTaxonomy: function(name, fn) { | |
this.authenticatedCall("wp.getTaxonomy", name, function(error, taxonomy) { | |
if (error) { | |
return fn(error); | |
} | |
fn(null, fieldMap.from(taxonomy, "taxonomy")); | |
}); | |
}, | |
getTaxonomies: function(fn) { | |
this.authenticatedCall("wp.getTaxonomies", function(error, taxonomies) { | |
if (error) { | |
return fn(error); | |
} | |
fn(null, taxonomies.map(function(taxonomy) { | |
return fieldMap.from(taxonomy, "taxonomy"); | |
})); | |
}); | |
}, | |
getTerm: function(taxonomy, id, fn) { | |
this.authenticatedCall("wp.getTerm", taxonomy, id, function(error, term) { | |
if (error) { | |
return fn(error); | |
} | |
fn(null, fieldMap.from(term, "term")); | |
}); | |
}, | |
getTerms: function(taxonomy, filter, fn) { | |
if (typeof filter === "function") { | |
fn = filter; | |
filter = {}; | |
} | |
if (filter.hideEmpty) { | |
filter.hide_empty = filter.hideEmpty; | |
delete filter.hideEmpty; | |
} | |
if (filter.orderby) { | |
filter.orderby = fieldMap.array([filter.orderby], "term")[0]; | |
} | |
this.authenticatedCall("wp.getTerms", taxonomy, filter, function(error, terms) { | |
if (error) { | |
return fn(error); | |
} | |
fn(null, terms.map(function(term) { | |
return fieldMap.from(term, "term"); | |
})); | |
}); | |
}, | |
newTerm: function(data, fn) { | |
this.authenticatedCall("wp.newTerm", fieldMap.to(data, "term"), fn); | |
}, | |
editTerm: function(id, data, fn) { | |
this.authenticatedCall("wp.editTerm", id, fieldMap.to(data, "term"), fn); | |
}, | |
deleteTerm: function(taxonomy, id, fn) { | |
this.authenticatedCall("wp.deleteTerm", taxonomy, id, fn); | |
} | |
}); | |
extend(Client.prototype, { | |
getMediaItem: function(id, fn) { | |
this.authenticatedCall("wp.getMediaItem", id, function(error, media) { | |
if (error) { | |
return fn(error); | |
} | |
fn(null, fieldMap.from(media, "media")); | |
}); | |
}, | |
getMediaLibrary: function(filter, fn) { | |
if (typeof filter === "function") { | |
fn = filter; | |
filter = {}; | |
} | |
this.authenticatedCall("wp.getMediaLibrary", filter, function(error, media) { | |
if (error) { | |
return fn(error); | |
} | |
fn(null, media.map(function(item) { | |
return fieldMap.from(item, "media"); | |
})); | |
}); | |
}, | |
uploadFile: function(data, fn) { | |
this.authenticatedCall("wp.uploadFile", fieldMap.to(data, "file"), fn); | |
} | |
}); | |
module.exports = { | |
Client: Client, | |
createClient: function(settings) { | |
return new Client(settings); | |
}, | |
fieldMap: fieldMap | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment