func_e 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/func_e/config.rb +13 -8
- data/lib/func_e/func.rb +4 -0
- data/lib/func_e/http.rb +33 -0
- data/lib/func_e.rb +21 -3
- data/lib/{func_e.js → func_e_runner.js} +1 -12
- data/lib/func_e_server.js +70 -0
- data/lib/support/args.js +16 -0
- data/lib/tasks/install/template/helloFn.js +1 -1
- metadata +9 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62bc0271fcdc97627a6886e2b4512f2a29f333c7530d710ef95d3de2a5e3a901
|
4
|
+
data.tar.gz: dd090d2dc79cfc3f4434177ad1053888f96f80319e978abf415e98ac6b6ff95c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b41b60fc486326b7c30c0fc4971b85a47fe0d197edd66274d4cccf21fd170b5605314996f375f808c23d560dbc5a9715b3a993b88d4c4273b5e380d1e9a772d3
|
7
|
+
data.tar.gz: 1449586c6ce48a0764ff6729f9cd5b9e4d31f76dc715b20421eef5bb887ec9fc152817a22b296039e7c4f24cc866e05077981e368b3dd261cb2f16c02f6bd324
|
data/lib/func_e/config.rb
CHANGED
@@ -8,29 +8,34 @@ module FuncE
|
|
8
8
|
class Config
|
9
9
|
include Singleton
|
10
10
|
|
11
|
+
DEFAULT_PORT = 3030
|
11
12
|
DEFAULT_INSTALL_DIR = 'funcs'
|
12
13
|
|
13
|
-
attr_accessor :fn_dir_path
|
14
|
+
attr_accessor :fn_dir_path, :local_server, :local_server_port
|
14
15
|
|
15
16
|
def self.configure
|
16
17
|
yield instance
|
18
|
+
|
19
|
+
# Set default values if they are not set.
|
20
|
+
instance.local_server ||= false
|
21
|
+
instance.local_server_port ||= DEFAULT_PORT
|
22
|
+
instance.fn_dir_path ||= DEFAULT_INSTALL_DIR
|
23
|
+
|
24
|
+
# Start the server if the local_server option is set to true.
|
25
|
+
FuncE::Http.start_server if instance.local_server
|
17
26
|
end
|
18
27
|
|
19
28
|
def self.config
|
20
29
|
instance
|
21
30
|
end
|
22
31
|
|
23
|
-
def self.get(key)
|
24
|
-
instance.send(key)
|
25
|
-
end
|
26
|
-
|
27
32
|
def self.install_path
|
28
33
|
if defined?(Rails)
|
29
|
-
Rails.root.join(
|
34
|
+
Rails.root.join(config.fn_dir_path)
|
30
35
|
elsif defined?(Bundler)
|
31
|
-
Bundler.root.join(
|
36
|
+
Bundler.root.join(config.fn_dir_path)
|
32
37
|
else
|
33
|
-
Pathname.new(Dir.pwd).join(
|
38
|
+
Pathname.new(Dir.pwd).join(config.fn_dir_path)
|
34
39
|
end
|
35
40
|
end
|
36
41
|
end
|
data/lib/func_e/func.rb
CHANGED
data/lib/func_e/http.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module FuncE
|
4
|
+
module Http
|
5
|
+
def self.uri
|
6
|
+
URI("http://localhost:#{FuncE::Config.config.local_server_port}")
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.headers
|
10
|
+
{ 'Content-Type': 'application/json' }
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.active_pid
|
14
|
+
`lsof -i:#{Config.config.local_server_port} -t`.to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.post(func)
|
18
|
+
Net::HTTP.post(uri, { name: func.name, payload: func.payload }.to_json, headers)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.start_server
|
22
|
+
kill_server
|
23
|
+
|
24
|
+
Thread.new {
|
25
|
+
system("node #{FuncE::SERVER_PATH} --port=#{Config.config.local_server_port} --functions_path=#{Config.install_path}")
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.kill_server
|
30
|
+
active_pid.tap { |pid| system("kill -9 #{pid}") unless pid.zero? }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/func_e.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'json'
|
3
4
|
require 'terrapin'
|
5
|
+
|
6
|
+
require 'func_e/http'
|
4
7
|
require 'func_e/func'
|
5
8
|
require 'func_e/config'
|
6
9
|
|
@@ -8,15 +11,30 @@ require 'func_e/config'
|
|
8
11
|
module FuncE
|
9
12
|
require 'railtie' if defined?(Rails)
|
10
13
|
|
11
|
-
RUNNER_PATH = "#{File.expand_path(__dir__)}/
|
14
|
+
RUNNER_PATH = "#{File.expand_path(__dir__)}/func_e_runner.js"
|
15
|
+
SERVER_PATH = "#{File.expand_path(__dir__)}/func_e_server.js"
|
12
16
|
|
13
17
|
def self.exec(func)
|
14
|
-
|
18
|
+
Config.config.local_server ? server(func) : runner(func)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.server(func)
|
22
|
+
json_parse FuncE::Http.post(func).body
|
23
|
+
rescue Errno::ECONNREFUSED
|
24
|
+
{ error: 'The server is not running. Please start the server before executing functions.' }
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.runner(func)
|
28
|
+
json_parse line.run(path: func.path, payload: func.serialize_payload)
|
15
29
|
rescue Terrapin::CommandLineError => e
|
16
30
|
{ error: 'An error occurred while executing the node function.', message: e.message }
|
17
31
|
end
|
18
32
|
|
19
33
|
def self.line
|
20
|
-
Terrapin::CommandLine.new("node #{RUNNER_PATH}", '--path=:path --payload=:payload'
|
34
|
+
Terrapin::CommandLine.new("node #{RUNNER_PATH}", '--path=:path --payload=:payload')
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.json_parse(json)
|
38
|
+
JSON.parse(json, symbolize_names: true)
|
21
39
|
end
|
22
40
|
end
|
@@ -9,18 +9,7 @@
|
|
9
9
|
* always return an Promise that resolves to the result of the function. Thus
|
10
10
|
* all functions must be asynchronous.
|
11
11
|
*/
|
12
|
-
|
13
|
-
/**
|
14
|
-
* Extract the arguments from the command line.
|
15
|
-
*/
|
16
|
-
let args = {};
|
17
|
-
|
18
|
-
process.argv.slice(2).forEach(arg => {
|
19
|
-
if (arg.startsWith('--')) {
|
20
|
-
const split = arg.indexOf('=');
|
21
|
-
args[arg.substring(2, split)] = arg.substring(split + 1);
|
22
|
-
}
|
23
|
-
})
|
12
|
+
const args = require('./support/args')();
|
24
13
|
|
25
14
|
// If any of the required arguments are missing, throw an error.
|
26
15
|
if (!args.path) throw new Error('Missing function name (--fn=<FUNCTION_NAME>');
|
@@ -0,0 +1,70 @@
|
|
1
|
+
const fs = require("fs");
|
2
|
+
const http = require("http");
|
3
|
+
|
4
|
+
// Get the port number from the cli arguments or use the default port number
|
5
|
+
const args = require("./support/args")();
|
6
|
+
|
7
|
+
const PORT = args.port || 3030;
|
8
|
+
|
9
|
+
/**
|
10
|
+
* Load all the functions from the provided directory.
|
11
|
+
*/
|
12
|
+
let functions = fs.readdirSync(args.functions_path).reduce((obj, file) => {
|
13
|
+
const isFunction = file.endsWith(".js");
|
14
|
+
|
15
|
+
if (isFunction) {
|
16
|
+
const functionName = file.split(".")[0];
|
17
|
+
const functionPath = args.functions_path + "/" + file;
|
18
|
+
obj[functionName] = require(functionPath);
|
19
|
+
}
|
20
|
+
|
21
|
+
return obj;
|
22
|
+
}, {});
|
23
|
+
|
24
|
+
const invalidRequestMethodError = JSON.stringify({
|
25
|
+
message: "This server only accepts POST requests"
|
26
|
+
})
|
27
|
+
|
28
|
+
const functionExecutionError = (err) => JSON.stringify({
|
29
|
+
error: err.message
|
30
|
+
});
|
31
|
+
|
32
|
+
const functionNotFoundError = (name) => JSON.stringify({
|
33
|
+
error: `Function "${name}" not loaded. Check the function name or restart the server.`
|
34
|
+
})
|
35
|
+
|
36
|
+
function setDefaultHeaders(res) {
|
37
|
+
res.setHeader("Content-Type", "application/json");
|
38
|
+
}
|
39
|
+
|
40
|
+
function handler(req, res) {
|
41
|
+
if (req.method != "POST") res.end(invalidRequestMethodError);
|
42
|
+
|
43
|
+
setDefaultHeaders(res)
|
44
|
+
|
45
|
+
let post_data = "";
|
46
|
+
|
47
|
+
req.on("data", chunk => post_data += chunk);
|
48
|
+
req.on("end", () => {
|
49
|
+
const data = JSON.parse(post_data);
|
50
|
+
const fn = functions[data.name];
|
51
|
+
|
52
|
+
if (!fn) {
|
53
|
+
res.statusCode = 404;
|
54
|
+
res.end(functionNotFoundError(data.name));
|
55
|
+
} else {
|
56
|
+
fn(data.payload)
|
57
|
+
.then((result) => {
|
58
|
+
res.statusCode = 200;
|
59
|
+
res.end(JSON.stringify(result));
|
60
|
+
}).catch((err) => {
|
61
|
+
res.statusCode = 500;
|
62
|
+
res.end(functionExecutionError(err));
|
63
|
+
});
|
64
|
+
}
|
65
|
+
});
|
66
|
+
}
|
67
|
+
|
68
|
+
const server = http.createServer(handler);
|
69
|
+
|
70
|
+
server.listen(PORT, () => console.log(`\nRunning FuncE server on http://localhost:${PORT}/\n`));
|
data/lib/support/args.js
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
/**
|
2
|
+
* Extract the arguments from the command line and return them as an object
|
3
|
+
* of key value pairs. Args are expected to be in the format --key=value.
|
4
|
+
*/
|
5
|
+
module.exports = () => {
|
6
|
+
let args = {};
|
7
|
+
|
8
|
+
process.argv.slice(2).forEach(arg => {
|
9
|
+
if (arg.startsWith('--')) {
|
10
|
+
const split = arg.indexOf('=');
|
11
|
+
args[arg.substring(2, split)] = arg.substring(split + 1);
|
12
|
+
}
|
13
|
+
})
|
14
|
+
|
15
|
+
return args;
|
16
|
+
};
|
metadata
CHANGED
@@ -1,41 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: func_e
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Scholl
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: json
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '2.0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '2.0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: terrapin
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
|
-
- - "
|
17
|
+
- - ">="
|
32
18
|
- !ruby/object:Gem::Version
|
33
19
|
version: '0.6'
|
34
20
|
type: :runtime
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
38
|
-
- - "
|
24
|
+
- - ">="
|
39
25
|
- !ruby/object:Gem::Version
|
40
26
|
version: '0.6'
|
41
27
|
description: FuncE is a lightweight Ruby gem that allows developers to call JavaScript
|
@@ -50,11 +36,14 @@ executables: []
|
|
50
36
|
extensions: []
|
51
37
|
extra_rdoc_files: []
|
52
38
|
files:
|
53
|
-
- lib/func_e.js
|
54
39
|
- lib/func_e.rb
|
55
40
|
- lib/func_e/config.rb
|
56
41
|
- lib/func_e/func.rb
|
42
|
+
- lib/func_e/http.rb
|
43
|
+
- lib/func_e_runner.js
|
44
|
+
- lib/func_e_server.js
|
57
45
|
- lib/railtie.rb
|
46
|
+
- lib/support/args.js
|
58
47
|
- lib/tasks/install/install.rake
|
59
48
|
- lib/tasks/install/template/helloFn.js
|
60
49
|
- lib/tasks/install/template/package.json
|
@@ -78,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
67
|
- !ruby/object:Gem::Version
|
79
68
|
version: '0'
|
80
69
|
requirements: []
|
81
|
-
rubygems_version: 3.5.
|
70
|
+
rubygems_version: 3.5.18
|
82
71
|
signing_key:
|
83
72
|
specification_version: 4
|
84
73
|
summary: FuncE provides an interface between Node.js functions and Ruby applications,
|