How to run custom wp-cli commands using node-wp-cli? - node.js

I am using node-wp-cli to run WP-cli commands from Node.js. All inbuilt WP-cli commands works perfectly but I stuck while trying to run my custom WP-cli commands.
Is there a way to to run my custom WP-Cli commands wp MyRegisteredCommand SubCommand from node-wp-cli? like:
WP.MyRegisteredCommand.SubCommand(function(err,res){ //get response
console.log(res);
});

This is relatively easy, but requires some tweaking...
Node wp-cli uses wp cli cmd-dump to identify the available commands, but this command runs before the WordPress is loaded, so it will recognize only the in-built commands.
The tweak in short:
See WP.js, line schema(function(err,schema){.... You need to know the structure of schema, so just run some in-built command and put a breakpoint here.
Implement the schema for your commands, following the schema structure above. It will look something like this:
my_commands.js:
var schema = {
mycmd: {
mysubcmd: {
args: [ {
arg: 'arg1',
required: true,
type: 'args'
} ],
endpoint: true,
options: {
opt1: {
required: true,
type: 'param'
},
flag1: {
required: false,
type: 'flag'
},
}
},
use: 'wp mycmd mysubcmd'
}
}
module.exports.schema = schema;
Modify WP.js:
var mySchema = require('my_commands.js').schema;
...
schema(function(err,schema){
schema = _.merge(schema, mySchema); // this line added
var toMerge = function mapSchema(schema){

Related

How can I add a Unique rule using indicative?

I am using Indicative in my project to validate my controller, but, Indicative don't have a "Unique" rule in "Validation Rules", but the framework Adonis have a rule call "unique" that does exactly what i need.
My project is made in Adonis, but i prefer to use "Indicative" and not "Validator" in Adonis, because i think is more easy and beautiful write the code direct in the Controller
code: 'required|string|max:255',
description: 'required|string|max:255|unique:tabela',
authors: 'string|max:255',
status: 'boolean',
user_id: 'integer',
created_at: [
importValidate.validations.dateFormat(['YYYY-MM-DD HH:mm:ss'])
],
updated_at: [
importValidate.validations.dateFormat(['YYYY-MM-DD HH:mm:ss'])
]
}
In the example above, I need the "code" to be "Unique" and return an error message and a response status. How can I do this?
The unique method of Validator will automatically search in the database. I don't think it's possible to do it with Indicative
I propose this solution (in your controller):
const { validate } = use('Validator')
...
const rules = {
code: 'unique:<table_name>,<field_name>'
}
const messages = {
'code.unique': '...'
}
const validation = await validate({ code: ... }, rules, messages)
if (validation.fails()) {
...
}
To use this command it is necessary to use Validator. I don't think there's an equivalent with Indicative

Sails.js - Get an object (model) using multiple join

I am new to node.js and newer to Sails.js framework.
I am currently trying to work with my database, I don't understand all the things with Sails.js but I manage to do what I want step by step. (I am used to some PHP MVC frameworks so it is not too difficult to understand the structure.)
Here I am trying to get a row from my database, using 2 JOIN clause. I managed to do this using SQL and the Model.query() function, but I would like to do this in a "cleaner" way.
So I have 3 tables in my database: meta, lang and meta_lang. It's quite simple and a picture being better than words, here are some screenshots.
meta
lang
meta_lang
What I want to do is to get the row in meta_table that match with 'default' meta and 'en' lang (for example).
Here are Meta and Lang models (I created them with sails generate model command and edited them with what I needed):
Meta
module.exports = {
attributes: {
code : { type: 'string' },
metaLangs:{
collection: 'MetaLang',
via: 'meta'
}
}
};
Lang
module.exports = {
attributes: {
code : { type: 'string' },
metaLangs:{
collection: 'MetaLang',
via: 'lang'
}
}
};
And here is my MetaLang model, with 3 functions I created to test several methods. The first function, findCurrent, works perfectly, but as you can see I had to write SQL. That is what I want to avoid if it is possible, I find it more clean (and I would like to use Sails.js tools as often as I can).
module.exports = {
tableName: 'meta_lang',
attributes: {
title : { type: 'string' },
description : { type: 'text' },
keywords : { type: 'string' },
meta:{
model:'Meta',
columnName: 'meta_id'
},
lang:{
model:'Lang',
columnName: 'lang_id'
}
},
findCurrent: function (metaCode, langCode) {
var query = 'SELECT ml.* FROM meta_lang ml INNER JOIN meta m ON m.id = ml.meta_id INNER JOIN lang l ON l.id = ml.lang_id WHERE m.code = ? AND l.code = ?';
MetaLang.query(query, [metaCode, langCode], function(err, metaLang) {
console.log('findCurrent');
if (err) return console.log(err);
console.log(metaLang);
// OK this works exactly as I want (I would have prefered a 'findOne' result, only 1 object instead of an array with 1 object in it, but I can do with it.)
});
},
findCurrentTest: function (metaCode, langCode) {
Meta.findByCode(metaCode).populate('metaLangs').exec(function(err, metaLang) {
console.log('findCurrentTest');
if (err) return console.log(err);
console.log(metaLang);
// I get what I expected (though not what I want): my meta + all metaLangs related to meta with code "default".
// What I want is to get ONE metaLang related to meta with code "default" AND lang with code "en".
});
},
findCurrentOthertest: function (metaCode, langCode) {
MetaLang.find().populate('meta', {where: {code:metaCode}}).populate('lang', {where: {code:langCode}}).exec(function(err, metaLang) {
console.log('findCurrentOthertest');
if (err) return console.log(err);
console.log(metaLang);
// Doesn't work as I wanted: it gets ALL the metaLang rows.
});
}
};
I also tried to first get my Meta by code, then my Lang by code, and MetaLang using Meta.id and Lang.id . But I would like to avoid 3 queries when I can have only one.
What I'm looking for would be something like MetaLang.find({meta.code:"default", lang.code:"en"}).
Hope you've got all needed details, just comment and ask for more if you don't.
Do you know what populate is for ? its for including the whole associated object when loading it from the database. Its practically the join you are trying to do, if all you need is row retrieval than quering the table without populate will make both functions you built work.
To me it looks like you are re-writing how Sails did the association. Id suggest giving the Associations docs another read in Sails documentation: Associations. As depending on your case you are just trying a one-to-many association with each table, you could avoid a middle table in my guess, but to decide better id need to understand your use-case.
When I saw the mySQL code it seemed to me you are still thinking in MySQL and PHP which takes time to convert from :) forcing the joins and middle tables yourself, redoing a lot of the stuff sails automated for you. I redone your example on 'disk' adapter and it worked perfectly. The whole point of WaterlineORM is to abstract the layer of going down to SQL unless absolutely necessary. Here is what I would do for your example, first without SQL just on a disk adapter id create the models :
// Lang.js
attributes: {
id :{ type: "Integer" , autoIncrement : true, primaryKey: true },
code :"string"
}
you see what i did redundantly here ? I did not really need the Id part as Sails does it for me. Just an example.
// Meta.js
attributes: {
code :"string"
}
better :) ?
// MetaLang.js
attributes:
{
title : "string",
desc : "string",
meta_id :
{
model : "meta",
},
lang_id :
{
model : "lang",
}
}
Now after simply creating the same values as your example i run sails console type :
MetaLang.find({meta_id : 1 ,lang_id:2}).exec(function(er,res){
console.log(res);
});
Output >>>
sails> [ { meta_id: 1,
lang_id: 2,
title: 'My blog',
id: 2 } ]
Now if you want to display what is meta with id 1 and what is lang with id 2, we use populate, but the referencing for join/search is just as simple as this.
sails> Meta_lang.find({meta_id : 1 ,lang_id:2}).populate('lang_id').populate('meta_id').exec(function(er,res){ console.log(res); });
undefined
sails> [ {
meta_id:
{ code: 'default',
id: 1 },
lang_id:
{ code: 'En',
id: 2 },
title: 'My blog',
id: 2 } ]
At this point, id switch adapters to MySQL and then create the MySQL tables with the same column names as above. Create the FK_constraints and voila.
Another strict policy you can add is to set up the 'via' and dominance on each model. you can read more about that in the Association documentation and it depends on the nature of association (many-to-many etc.)
To get the same result without knowing the Ids before-hand :
sails> Meta.findOne({code : "default"}).exec(function(err,needed_meta){
..... Lang.findOne({code : "En"}).exec(function(err_lang,needed_lang){
....... Meta_lang.find({meta_id : needed_meta.id , lang_id : needed_lang.id}).exec(function(err_all,result){
......... console.log(result);});
....... });
..... });
undefined
sails> [ { meta_id: 1,
lang_id: 2,
title: 'My blog',
id: 2 } ]
Have you tried:
findCurrentTest: function (metaCode, langCode) {
Meta.findByCode(metaCode).populate('metaLangs', {where: {code:langCode}}).exec(function(err, metaLang) {
console.log('findCurrentTest');
if (err) return console.log(err);
console.log(metaLang);
});
},

aws-sdk javascript filter on tag:key=value

Folks,
I am having difficult time understanding the docs http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/frames.html
I need to grab all the running instances with the following tags assigned to them:
project=foo
environment=production
The following does not seem to work.
var params = {
DryRun: false,
Filters: [
{
Name: 'instance-state-name',
Values: [
'running'
],
},
{
Name: 'tag:key=value',
Values: [
'foo',
'production'
],
},
]
};
ec2.describeInstances(params, function (err, data) {
...
If your tag's key is 'foo' and its value is 'production', you should change your code to the following. The Name is in the 'tag:key' format, and the Values are the data you are looking for that correspond to that key.
{
Name: 'tag:foo',
Values: [
'production'
],
},
This is slightly related, and may help anyone who found there way here like I did.
I was trying check if an Instance with a tag Name=myInstance, was running in my aws account.
It's pretty difficult to check existence of resources in aws, but clairestreb's answer led me to the work around for this case.
I've begun developing a library of other such work arounds, and with it you can now do this:
Find Running Instance with tag Name=myInstance
var ex = require('aws-existence')
var ec2 = ex.ec2({region: 'us-west-2'})
ec2.doesInstanceExist('myInstance', 'running')
.then(doSomething)
function doSomething (exists) {
if (exists) {
// stop it?
} else {
// start it?
}
}
So that's doesInstanceExist(identifier, instanceState) where the identifier is a name tag, or an InstanceId. And state is optionally any one of the instance-state-name values. If you omit the state, it will tell you if an instance in any of the states exists.
You can find the library here:
nackjicholson/aws-existence

Error: text search not enabled:- in mongodb

I get the following error :-
[Error: text search not enabled]
I am running the folliowing function which is essentially a mongoose-mongodb operation.
var textSearch = require('mongoose-text-search');
exports.dbTextSearch = function () {
console.log('dbTextSearch');
var gameSchema = mongoose.Schema({
name: String
, tags: [String]
, likes: Number
, created: Date
});
gameSchema.plugin(textSearch);
gameSchema.index({ tags: 'text' });
var Game = mongoose.model('Game', gameSchema);
Game.create({ name: 'Super Mario 64', tags: ['nintendo', 'mario', '3d'] }, function (err) {
Game.textSearch('3d', function (err, output) {
if (err) return console.log(err); // this outputs the error.
var inspect = require('util').inspect;
console.log(inspect(output, { depth: null }));
});
});
}
I am trying to implement the mongoose-text-search plugin
In MongoDB 2.4 - to enable the experimental text search, use
setParameter=textSearchEnabled=true
The following line didn't work for me in the mongodb.conf file.
textSearchEnabled=true
EDIT In MongoDB 2.6 + it is enabled by default. You just need to set up your text indexes.
MongoDB Text search is still an experimental feature. That's why it is disabled by default and must be enabled manually. You can do so by either starting mongod with the command line parameter --setParameter textSearchEnabled=true or adding the line textSearchEnabled=true to the file mongodb.conf.
Please note that as an experimental feature, text search should not be used in a production environment yet.
UPDATE
As of version 2.6 of mongoDB text search feature has production-quality and is enabled automatically.
You have to specify this startup parameter (mentioned in above answers) when you start mongo. So if you start manually, then use:
mongod --setParameter textSearchEnabled=true
Otherwise, if mongo is deamonized, put it into deamon script. Something like this:
start()
{
echo -n $"Starting mongod: "
daemon --user "$MONGO_USER" $NUMACTL $mongod --setParameter textSearchEnabled=true $OPTIONS
Then you create text index and check it's existence:
db.mycoll.createIndex( { someFieldName: "text" } );
db.mycoll.getIndexes()

CompoundJS: Populating database with seed file hangs

I'm trying to populate my CompoundJS application's Mongo database with seed files, but whenever I run compound seed, the terminal hangs after my console.log statements... the database fills, but I have to kill the command with Ctrl-c.
I've tried doing compound seed harvest, but that doesn't create proper seed files, so I've decided to make my own. Here is my respective code:
db/seeds/development/Host.js (seed file)
console.log("Seeding Hosts....");
var hosts = [
{
hid: '1',
name: 'MY API',
domain: 'mydomain.com'
}
];
hosts.forEach(function(obj, err){
Host.create(obj, function(err, host){
console.log('host Added: ', host);
});
});
db/schema.js
var Host = describe('Host', function () {
property('hid', String);
property('name', String);
property('domain', String);
set('restPath', pathTo.hosts);
});
config/database.js
module.exports = {
development: {
driver: 'mongodb',
url: 'mongodb://localhost/apicache-dev'
},
test: {
driver: 'mongodb',
url: 'mongodb://localhost/apicache-test'
},
production: {
driver: 'mongodb',
url: 'mongodb://localhost/apicache-production'
}
};
Like I said, when I run compound seed, it shows both console.log statements, and it puts my data into the database, but it just hangs... never actually returning to the command line, so I'm forced to kill it with Ctrl-c. I would like to solve this problem, as I have to automate this process, and it's a bit hard automating if it's just hanging. What am I doing wrong? Any help would be appreciated!
Cross-posted.
EDIT
So when I try to use the Coffee script version that's generated from compound seed harvest:
db/seeds/development/Host.coffee
Host.seed ->
hid: '1'
name: 'MY API'
domain: 'mydomain.com'
id: "52571edd2ac9056339000001"
I get the error collection name must be a String. So I was a little curious and went to where that error was being generated... in node_modules/jugglingdb-mongodb/node_modules/mongodb/lib/mongodb/collection.js on line 103. I put a console.log(collectionName) right before that if statement and saw an interesting output...
{ hid: '1',
name: 'MY API',
domain: 'mydomain.com',
id: NaN }
So clearly it's not a string, but a hash object, and my collection's name (Host) is nowhere in sight. Seems like a bug to me.
So I finally got it to work. Apparently, there was something wrong with the auto-genned id from the harvest command, so I ended up deleting that line, and voila! Planting the seeds works like a charm. I converted the rest of my JS files to Coffee script files and everything works. Sometimes you just need to have a conversation with yourself on the Internet...
Here's my seed file:
Host.seed ->
hid: '1'
name: 'MY API'
domain: 'mydomain.com'
And doing compound seed works without hanging and populates the database. Guess Coffee script is the way to go?

Resources