Execjs to Execute nodejs code from Ruby with some extra node_module - ruby-on-rails

I have ruby on rails env I like to execute nodejs command from my rails application.
I able to execute below scrip and it's works
require 'execjs'
context = ExecJS.compile('function double(x) { return x * 2 }')
puts context.call('double', 10)
now i like to use some extra node module to use.
context = ExecJS.compile('var redis = require('redis');
var client = redis.createClient();client.on('connect', function() { console.log('Redis client connected');});
function selectdb(number) { client.select(number);}')
context.call('selectdb', 1)
it gives me an error on require block that we not inject external node module.
is there any way I can inject extra module on my runtime code block.
I see some solution/workaround with stitch-rb but it not works.
please suggest if I am doing something wrong or any another way to use nodejs code from Rails application.

You cannot do this, at least not with the vanilla implementation of ExecJS. (a suggested alternative is using commonjs.rb)
Check the FAQ here:
Why can't I use CommonJS require() inside ExecJS?
ExecJS provides a lowest common denominator interface to any
JavaScript runtime. Use ExecJS when it doesn't matter which JavaScript
interpreter your code runs in. If you want to access the Node API, you
should check another library like commonjs.rb designed to provide a
consistent interface.

Related

How do you authenticate with an API key inside an IBM Cloud Function?

I am writing an IBM Cloud Function which uses the python SDK to interface with a Cloudant service. I have the Cloudant service up, the databases populated, and service credentials / API key ready. However when I try to instantiate the CloudantV1 service inside my Function I get a runtime error "must provide authenticator".
I looked up the error in their git repos and it seems like it is trying to setup an authenticator object by looking up values from environment variables, which do not exist in the Function. I just want to pass my API key directly, but I have not found a method to do this. I am using basic code from the examples so I think my calls are correct.
I have considered injecting the environment variables inside the Function, but that sounds like a major hack. I must be doing something incorrectly. Please help me understand what it is. Here is basic Function python code which reproduces the error:
from ibmcloudant.cloudant_v1 import CloudantV1
def main(params_dict):
service = CloudantV1.new_instance()
# unreachable
return { "message" : "hello world" }
There is an example for programmatic authentication at https://cloud.ibm.com/apidocs/cloudant?code=python#programmatic-authentication - it basically looks like this:
from ibmcloudant.cloudant_v1 import CloudantV1
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
authenticator = IAMAuthenticator('yourAPIkey')
service = CloudantV1(authenticator=authenticator)
service.set_service_url('https://yourserviceurl.example')

is it possible to call require from C

I have a module compiled in a shared object (I followed the library part of this article https://chsasank.github.io/lua-c-wrapping.html) and I want to load it from C not from the interpreter.
Is it possible ? If so how to do it ?
Yes, it's possible, as require is a function stored in a global environment. Lua does the same in standalone interpreter when it needs to process the -l option, see the dolibrary function.
You do this the same way as with any other global function - in simplest case calling lua_getglobal(), then pushing the name of the file to require, and calling lua_call/lua_pcall/whatever.
I know that I am late, but someone else may struggle with this right now (like I just did).
This is a simple way of doing "require" from C:
int reqRes = luaL_dostring(L, "local t=require('myLib') return (t~=nil)");
if (reqRes==0)
//success
else
//failed
Unfortunately, right now, I'm using Lua 5.1 and "dolibrary" function doesn't exist, I >tried to take some part of the code and it crashes :\ So, for now, I use luaL_dostring(L, >"require 'libMyWrappings'"); libMyWrappings must be in the same directory as the c >program, and I can't use a path to indicate the lib. – Aminos Jan 22 at 11:45
I just ran into the same issue, it has to do when the package library is loaded
{LUA_LOADLIBNAME, luaopen_package}
needs to happen before you try and call it

How can I make a firefox add-on contentscript inject and run a script before other page scripts?

I'm working on a Browser extension/add-on. We have it working in Chrome, so I'm trying to get it working in Firefox.
I've gotten my add-on to load in Firefox Developer Edition 49.0a2 (2016-07-25).
My extension involves a content_script set to run_at: document_start, so it can inject a script tag before other page scripts run, so it can make an object globally available to websites.
This has seemed to work fine in Chrome, but in Firefox it has proven to be a bit of a race condition, with other page resources loading first most of the time.
Is there a strategy to load a content script in a way that it can inject & load a script before any other page scripts run?
When I add logs, I can isolate what is happening pretty nicely. In this example content-script:
// inject in-page script
console.log('STEP 1, this always happens first')
var scriptTag = document.createElement('script')
scriptTag.src = chrome.extension.getURL('scripts/inpage.js')
scriptTag.onload = function () { this.parentNode.removeChild(this) }
var container = document.head || document.documentElement
// append as first child
container.insertBefore(scriptTag, container.children[0])
Now if the file scripts/inpage.js simply runs a log, like
console.log('STEP 2, this should always run second')
And I visit a page with a script like this:
console.log('Step 3, the page itself, should run last')
In practice, Step 2 and Step 3 run in a non-deterministic order.
Thanks a lot!
I have Firefox-compatible version of the script in a public repository on a special branch if you dare to try it yourself: https://github.com/MetaMask/metamask-plugin/tree/FirefoxCompatibility
An dynamically inserted script with an external source (<script src>) does not block the execution of scripts, so there is no guarantee that your script would load. If your extension worked in Chrome, it was just by sheer luck.
If you really want to run some script before the rest, you have to run it inline:
var actualCode = `
// Content of scripts/inpage.js here
`;
var s = document.createElement('script');
s.textContent = actualCode;
(document.head || document.documentElement).appendChild(s);
s.remove();
Ideally, your build script would read scripts/inpage.js, serialize it to a string and put it in the actualCode variable. But if inpage.js is just a few lines of code, then the above can be used.
Note that you should not inject code in the web page unless it is absolutely necessary. The reason for that is that the execution environment of the page is untrusted. If you inject at document_start, then you can save functions and (prototype) methods that use for later (in a closure), but very careful coding is required.
If your content script is not generated by a build script and you still want to keep the scripts separate, then you can also use synchronous XMLHttpRequest to fetch the script. Synchronous XHR is deprecated for performance reasons, so use it at your own risk. Extension code is typically bundled with your extension, so the use of sync xhr should be low-risk:
// Note: do not use synchronous XHR in production!
var x = new XMLHttpRequest();
x.open('GET', chrome.runtime.getURL('scripts/inpage.js'), false);
x.send();
var actualCode = x.responseText;
var s = document.createElement('script');
s.textContent = actualCode;
(document.head || document.documentElement).appendChild(s);
s.remove();
If you are using a bootstrap.js based addon you can use a framescript and DOMWindowCreated to work with the document before even the HTML DOM (past basics of document.body etc) renders - https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Frame_script_environment#Events - the innerHTML will be available but no script would have executed. You can put your inline script at the top as #Rob mentioned.

"attempt to call global 'tonumber' (a nil value)" in Lua, embedded (in VLC)

I use VLC media player 1.1.9 on Ubuntu 11.04. I'm trying to experiment with lua extensions for VLC; so I've added the file test.lua in ~/.local/share/vlc/lua/extensions/, which has only these two lines:
fps="25.000"
frame_duration=1/tonumber(fps)
When I run vlc with verbose output for debugging, I get (edited to split on multiple lines:):
$ vlc --verbose 2
...
[0xa213874] lua generic warning: Error loading script
~/.local/share/vlc/lua/extensions/test.lua:
.../.local/share/vlc/lua/extensions/test.lua:2:
attempt to call global 'tonumber' (a nil value)
...
Now, as far as I know, tonumber as function is part of Lua5.1 proper (Lua 5.1 Reference Manual: tonumber) - and on my system:
$ locate --regex 'lua.*so.*' | head -4
/usr/lib/libipelua.so.7.0.10
/usr/lib/liblua5.1.so
/usr/lib/liblua5.1.so.0
/usr/lib/liblua5.1.so.0.0.0
... apparently I do have Lua 5.1 installed.
So, why do I get an error on using tonumber here - and how can I use this (and other) standard functions in a VLC lua extension properly?
Documentation is sparse for VLC Lua extensions to say the least but I did find an example in the github vlc repository here: https://github.com/videolan/vlc/blob/master/share/lua/extensions/VLSub.lua
Judging from that example it appears you need to supply some basic event functions for your addon for VLC to call into when certain events happen. Some of the obvious callback handlers I've noticed:
descriptor, this should return a table that contains fields describing your addon.
activate, this seems to get called when you activate it from view menubar.
deactivate, called when you deactivate the addon from view menubar.
plus a couple of other functions like close and input_change which you can guess what they're for.
From my brief testing done on VLC 2.0.8 under Win7 it appears VLC loads the lua extension using an empty sandbox environment. This is likely the reason you're getting nil for tonumber and I'm betting none of the other standard lua functions are accessible either when you try to perform computation at this global scope.
However, if I move that code into one of the event handling functions then all those standard functions are accessible again. For example:
function descriptor()
return
{
title = "Test Ext";
version = "0.1";
author = "";
shortdesc = "Testing Lua Extension";
capabilities = {};
description = "VLC Hello Test Addon";
}
end
function activate()
print "test activating"
local fps = tonumber "25.000"
local frame_duration = 1 / fps
print(frame_duration)
return true
end
-- ...
That prints out what you would expect in the console debug log. Now the documentation (what little there is) doesn't mention any of this but what's probably happening here is VLC is injecting the standard lua functions and vlc api table into the sandboxed environment when any of these event handlers get called. But during the extension loading phase, it is done in an empty sandbox environment which explains why all those lua function calls end up being nil when you try to use it at the outter most scope.
I recommend cloning the VLC source tree from github and then performing a grep on the C source that's embedding lua to see what VLC is really doing behind the scenes. Most of the relevant code will likely be here: https://github.com/videolan/vlc/tree/master/modules/lua
Probably some extension script installed in your system overwrites the function and the Lua interpreter instance is shared between all extension scripts, so you end up not being able to call the function if that script is called before yours.
As a quick workaround, Lua being dynamically typed, you can still do things like:
1 / "25.000"
and the string will be coerced to a number.
Alternatively, you can define a tonumber equivalent like:
string_to_num = function(s) return s + 0 end
This again relies on dynamic typing.

Equivalence of Rails console for Node.js

I am trying out Node.js Express framework, and looking for plugin that allows me to interact with my models via console, similar to Rails console. Is there such a thing in NodeJS world?
If not, how can I interact with my Node.js models and data, such as manually add/remove objects, test methods on data etc.?
Create your own REPL by making a js file (ie: console.js) with the following lines/components:
Require node's built-in repl: var repl = require("repl");
Load in all your key variables like db, any libraries you swear by, etc.
Load the repl by using var replServer = repl.start({});
Attach the repl to your key variables with replServer.context.<your_variable_names_here> = <your_variable_names_here>. This makes the variable available/usable in the REPL (node console).
For example: If you have the following line in your node app:
var db = require('./models/db')
Add the following lines to your console.js
var db = require('./models/db');
replServer.context.db = db;
Run your console with the command node console.js
Your console.js file should look something like this:
var repl = require("repl");
var epa = require("epa");
var db = require("db");
// connect to database
db.connect(epa.mongo, function(err){
if (err){ throw err; }
// open the repl session
var replServer = repl.start({});
// attach modules to the repl context
replServer.context.epa = epa;
replServer.context.db = db;
});
You can even customize your prompt like this:
var replServer = repl.start({
prompt: "Node Console > ",
});
For the full setup and more details, check out:
http://derickbailey.com/2014/07/02/build-your-own-app-specific-repl-for-your-nodejs-app/
For the full list of options you can pass the repl like prompt, color, etc: https://nodejs.org/api/repl.html#repl_repl_start_options
Thank you to Derick Bailey for this info.
UPDATE:
GavinBelson has a great recommendation for running with sequelize ORM (or anything that requires promise handling in the repl).
I am now running sequelize as well, and for my node console I'm adding the --experimental-repl-await flag.
It's a lot to type in every time, so I highly suggest adding:
"console": "node --experimental-repl-await ./console.js"
to the scripts section in your package.json so you can just run:
npm run console
and not have to type the whole thing out.
Then you can handle promises without getting errors, like this:
const product = await Product.findOne({ where: { id: 1 });
I am not very experienced in using node, but you can enter node in the command line to get to the node console. I then used to require the models manually
Here is the way to do it, with SQL databases:
Install and use Sequelize, it is Node's ORM answer to Active Record in Rails. It even has a CLI for scaffolding models and migrations.
node --experimental-repl-await
> models = require('./models');
> User = models.User; //however you load the model in your actual app this may vary
> await User.findAll(); //use await, then any sequelize calls here
TLDR
This gives you access to all of the models just as you would in Rails active record. Sequelize takes a bit of getting used to, but in many ways it is actually more flexible than Active Record while still having the same features.
Sequelize uses promises, so to run these properly in REPL you will want to use the --experimental-repl-await flag when running node. Otherwise, you can get bluebird promise errors
If you don't want to type out the require('./models') step, you can use console.js - a setup file for REPL at the root of your directory - to preload this. However, I find it easier to just type this one line out in REPL
It's simple: add a REPL to your program
This may not fully answer your question, but to clarify, node.js is much lower-level than Rails, and as such doesn't prescribe tools and data models like Rails. It's more of a platform than a framework.
If you are looking for a more Rails-like experience, you may want to look at a more 'full-featured' framework built on top of node.js, such as Meteor, etc.

Resources