@port-labs/jq-node-bindings 0.0.1
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.
- package/.editorconfig +5 -0
- package/.jshintignore +1 -0
- package/.jshintrc +23 -0
- package/binding.gyp +56 -0
- package/configure +26 -0
- package/deps/jq/.gitattributes +2 -0
- package/deps/jq/.travis.yml +53 -0
- package/deps/jq/AUTHORS +73 -0
- package/deps/jq/COPYING +70 -0
- package/deps/jq/ChangeLog +1349 -0
- package/deps/jq/Makefile.am +198 -0
- package/deps/jq/NEWS +88 -0
- package/deps/jq/README.md +64 -0
- package/deps/jq/builtin.c +1684 -0
- package/deps/jq/builtin.h +10 -0
- package/deps/jq/bytecode.c +161 -0
- package/deps/jq/bytecode.h +92 -0
- package/deps/jq/compile-ios.sh +102 -0
- package/deps/jq/compile.c +1210 -0
- package/deps/jq/compile.h +101 -0
- package/deps/jq/config/m4/check-math-func.m4 +4 -0
- package/deps/jq/config/m4/find-func-no-libs.m4 +8 -0
- package/deps/jq/config/m4/find-func-no-libs2.m4 +62 -0
- package/deps/jq/config/m4/find-func.m4 +9 -0
- package/deps/jq/config/m4/misc.m4 +3 -0
- package/deps/jq/configure.ac +221 -0
- package/deps/jq/docs/Gemfile +7 -0
- package/deps/jq/docs/Gemfile.lock +63 -0
- package/deps/jq/docs/README.md +25 -0
- package/deps/jq/docs/Rakefile +145 -0
- package/deps/jq/docs/content/1.tutorial/default.yml +327 -0
- package/deps/jq/docs/content/2.download/default.yml +117 -0
- package/deps/jq/docs/content/3.manual/manual.yml +2878 -0
- package/deps/jq/docs/content/3.manual/v1.3/manual.yml +1270 -0
- package/deps/jq/docs/content/3.manual/v1.4/manual.yml +1672 -0
- package/deps/jq/docs/content/index/index.yml +51 -0
- package/deps/jq/docs/default_manpage.md +22 -0
- package/deps/jq/docs/public/.htaccess +28 -0
- package/deps/jq/docs/public/bootstrap/css/bootstrap-responsive.css +1058 -0
- package/deps/jq/docs/public/bootstrap/css/bootstrap-responsive.min.css +9 -0
- package/deps/jq/docs/public/bootstrap/css/bootstrap.css +5224 -0
- package/deps/jq/docs/public/bootstrap/css/bootstrap.min.css +9 -0
- package/deps/jq/docs/public/bootstrap/img/glyphicons-halflings-white.png +0 -0
- package/deps/jq/docs/public/bootstrap/img/glyphicons-halflings.png +0 -0
- package/deps/jq/docs/public/bootstrap/js/bootstrap.js +2027 -0
- package/deps/jq/docs/public/bootstrap/js/bootstrap.min.js +6 -0
- package/deps/jq/docs/public/css/base.scss +99 -0
- package/deps/jq/docs/public/jq.png +0 -0
- package/deps/jq/docs/public/robots.txt +2 -0
- package/deps/jq/docs/site.yml +18 -0
- package/deps/jq/docs/templates/default.liquid +34 -0
- package/deps/jq/docs/templates/index.liquid +60 -0
- package/deps/jq/docs/templates/manual.liquid +122 -0
- package/deps/jq/docs/templates/shared/_footer.liquid +5 -0
- package/deps/jq/docs/templates/shared/_head.liquid +12 -0
- package/deps/jq/docs/templates/shared/_header.liquid +26 -0
- package/deps/jq/exec_stack.h +112 -0
- package/deps/jq/execute.c +1155 -0
- package/deps/jq/inject_errors.c +112 -0
- package/deps/jq/jq.1.default +39 -0
- package/deps/jq/jq.1.prebuilt +3075 -0
- package/deps/jq/jq.h +60 -0
- package/deps/jq/jq.spec +70 -0
- package/deps/jq/jq_parser.h +9 -0
- package/deps/jq/jq_test.c +346 -0
- package/deps/jq/jv.c +1333 -0
- package/deps/jq/jv.h +240 -0
- package/deps/jq/jv_alloc.c +179 -0
- package/deps/jq/jv_alloc.h +27 -0
- package/deps/jq/jv_aux.c +619 -0
- package/deps/jq/jv_dtoa.c +4275 -0
- package/deps/jq/jv_dtoa.h +22 -0
- package/deps/jq/jv_file.c +49 -0
- package/deps/jq/jv_parse.c +852 -0
- package/deps/jq/jv_print.c +348 -0
- package/deps/jq/jv_unicode.c +96 -0
- package/deps/jq/jv_unicode.h +11 -0
- package/deps/jq/jv_utf8_tables.h +37 -0
- package/deps/jq/lexer.c +2442 -0
- package/deps/jq/lexer.h +362 -0
- package/deps/jq/lexer.l +184 -0
- package/deps/jq/libm.h +160 -0
- package/deps/jq/linker.c +393 -0
- package/deps/jq/linker.h +7 -0
- package/deps/jq/locfile.c +91 -0
- package/deps/jq/locfile.h +29 -0
- package/deps/jq/m4/ax_compare_version.m4 +177 -0
- package/deps/jq/m4/ax_prog_bison_version.m4 +68 -0
- package/deps/jq/main.c +566 -0
- package/deps/jq/opcode_list.h +44 -0
- package/deps/jq/parser.c +3914 -0
- package/deps/jq/parser.h +193 -0
- package/deps/jq/parser.y +923 -0
- package/deps/jq/scripts/crosscompile +42 -0
- package/deps/jq/scripts/gen_utf8_tables.py +32 -0
- package/deps/jq/scripts/version +5 -0
- package/deps/jq/setup.sh +33 -0
- package/deps/jq/tests/jq.test +1235 -0
- package/deps/jq/tests/jqtest +5 -0
- package/deps/jq/tests/mantest +7 -0
- package/deps/jq/tests/modules/.jq +5 -0
- package/deps/jq/tests/modules/a.jq +2 -0
- package/deps/jq/tests/modules/b/b.jq +2 -0
- package/deps/jq/tests/modules/c/c.jq +16 -0
- package/deps/jq/tests/modules/c/d.jq +1 -0
- package/deps/jq/tests/modules/data.json +4 -0
- package/deps/jq/tests/modules/lib/jq/e/e.jq +1 -0
- package/deps/jq/tests/modules/lib/jq/f.jq +1 -0
- package/deps/jq/tests/modules/syntaxerror/syntaxerror.jq +1 -0
- package/deps/jq/tests/modules/test_bind_order.jq +4 -0
- package/deps/jq/tests/modules/test_bind_order0.jq +1 -0
- package/deps/jq/tests/modules/test_bind_order1.jq +2 -0
- package/deps/jq/tests/modules/test_bind_order2.jq +2 -0
- package/deps/jq/tests/onig.supp +21 -0
- package/deps/jq/tests/onig.test +85 -0
- package/deps/jq/tests/onigtest +5 -0
- package/deps/jq/tests/setup +36 -0
- package/deps/jq/tests/shtest +205 -0
- package/deps/jq/tests/torture/input0.json +7 -0
- package/deps/jq/util.c +462 -0
- package/deps/jq/util.h +64 -0
- package/deps/jq.gyp +35 -0
- package/index.d.ts +3 -0
- package/jest.config.js +10 -0
- package/lib/index.js +14 -0
- package/package.json +48 -0
- package/reports/jest-port-api.xml +35 -0
- package/src/binding.cc +177 -0
- package/src/binding.h +13 -0
- package/test/santiy.test.js +122 -0
- package/util/configure.js +27 -0
package/src/binding.cc
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
#include "src/binding.h"
|
|
2
|
+
#include <list>
|
|
3
|
+
#include <unordered_map>
|
|
4
|
+
#include <assert.h>
|
|
5
|
+
|
|
6
|
+
using namespace std;
|
|
7
|
+
|
|
8
|
+
// LRUCache to save filter to the compiled jq_state
|
|
9
|
+
template <class KEY_T, class VAL_T> class LRUCache{
|
|
10
|
+
private:
|
|
11
|
+
list< pair<KEY_T,VAL_T> > item_list;
|
|
12
|
+
unordered_map<KEY_T, decltype(item_list.begin()) > item_map;
|
|
13
|
+
size_t cache_size;
|
|
14
|
+
private:
|
|
15
|
+
void clean(void){
|
|
16
|
+
while(item_map.size()>cache_size){
|
|
17
|
+
auto last_it = item_list.end(); last_it --;
|
|
18
|
+
item_map.erase(last_it->first);
|
|
19
|
+
item_list.pop_back();
|
|
20
|
+
jq_teardown(&last_it->second);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
public:
|
|
24
|
+
LRUCache(int cache_size_):cache_size(cache_size_){
|
|
25
|
+
;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
void put(const KEY_T &key, const VAL_T &val){
|
|
29
|
+
auto it = item_map.find(key);
|
|
30
|
+
if(it != item_map.end()){
|
|
31
|
+
item_list.erase(it->second);
|
|
32
|
+
item_map.erase(it);
|
|
33
|
+
}
|
|
34
|
+
item_list.push_front(make_pair(key,val));
|
|
35
|
+
item_map.insert(make_pair(key, item_list.begin()));
|
|
36
|
+
clean();
|
|
37
|
+
};
|
|
38
|
+
bool exist(const KEY_T &key){
|
|
39
|
+
return (item_map.count(key)>0);
|
|
40
|
+
};
|
|
41
|
+
VAL_T get(const KEY_T &key){
|
|
42
|
+
assert(exist(key));
|
|
43
|
+
auto it = item_map.find(key);
|
|
44
|
+
item_list.splice(item_list.begin(), item_list, it->second);
|
|
45
|
+
return it->second->second;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
LRUCache<std::string, jq_state*> cache(100);
|
|
51
|
+
|
|
52
|
+
void jv_object_to_v8(std::string key, jv actual, v8::Local<v8::Object> ret) {
|
|
53
|
+
jv_kind k = jv_get_kind(actual);
|
|
54
|
+
|
|
55
|
+
v8::Local<v8::String> v8_key = Nan::New(key).ToLocalChecked();
|
|
56
|
+
v8::Local<v8::Value> v8_val;
|
|
57
|
+
|
|
58
|
+
switch (k) {
|
|
59
|
+
case JV_KIND_NULL: {
|
|
60
|
+
v8_val = Nan::Null();
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case JV_KIND_TRUE: {
|
|
64
|
+
v8_val = Nan::True();
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
case JV_KIND_FALSE: {
|
|
68
|
+
v8_val = Nan::False();
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case JV_KIND_NUMBER: {
|
|
72
|
+
v8_val = Nan::New(jv_number_value(actual));
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case JV_KIND_STRING: {
|
|
76
|
+
v8_val = Nan::New(jv_string_value(actual)).ToLocalChecked();
|
|
77
|
+
jv_free(actual);
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
case JV_KIND_ARRAY: {
|
|
81
|
+
v8::Local<v8::Array> ret_arr = Nan::New<v8::Array>();
|
|
82
|
+
for (int i = 0; i < jv_array_length(jv_copy(actual)); i++) {
|
|
83
|
+
jv_object_to_v8(std::to_string(i), jv_array_get(jv_copy(actual), i), ret_arr);
|
|
84
|
+
}
|
|
85
|
+
Nan::Set(ret, v8_key, ret_arr);
|
|
86
|
+
jv_free(actual);
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
case JV_KIND_OBJECT: {
|
|
90
|
+
v8::Local<v8::Object> ret_obj = Nan::New<v8::Object>();
|
|
91
|
+
jv_object_foreach(actual, itr_key, value) {
|
|
92
|
+
jv_object_to_v8(jv_string_value(itr_key), value, ret_obj);
|
|
93
|
+
}
|
|
94
|
+
jv_free(actual);
|
|
95
|
+
Nan::Set(ret, v8_key, ret_obj);
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (v8_val.IsEmpty()) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
Nan::Set(ret, v8_key, v8_val);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
void jq_exec(std::string json, std::string filter,const Nan::FunctionCallbackInfo<v8::Value>& info) {
|
|
108
|
+
jq_state *jq = NULL;
|
|
109
|
+
|
|
110
|
+
if (cache.exist(filter)) {
|
|
111
|
+
jq = cache.get(filter);
|
|
112
|
+
} else {
|
|
113
|
+
jq = jq_init();
|
|
114
|
+
if (!jq_compile(jq, filter.c_str())) {
|
|
115
|
+
info.GetReturnValue().Set(Nan::Null());
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
cache.put(filter, jq);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
jv input = jv_parse(json.c_str());
|
|
122
|
+
|
|
123
|
+
if (!jv_is_valid(input)) {
|
|
124
|
+
info.GetReturnValue().Set(Nan::Null());
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (jq == NULL) {
|
|
129
|
+
info.GetReturnValue().Set(Nan::Null());
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
jq_start(jq, input, 0);
|
|
134
|
+
|
|
135
|
+
jv actual = jq_next(jq);
|
|
136
|
+
jv_kind k = jv_get_kind(actual);
|
|
137
|
+
|
|
138
|
+
v8::Local<v8::Object> ret = Nan::New<v8::Object>();
|
|
139
|
+
|
|
140
|
+
jv_object_to_v8("value", actual, ret);
|
|
141
|
+
|
|
142
|
+
info.GetReturnValue().Set(ret);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
std::string FromV8String(v8::Local<v8::String> val) {
|
|
147
|
+
Nan::Utf8String keyUTF8(val);
|
|
148
|
+
return std::string(*keyUTF8);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
void Exec(const Nan::FunctionCallbackInfo<v8::Value>& info) {
|
|
152
|
+
v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
|
|
153
|
+
|
|
154
|
+
if (info.Length() < 2) {
|
|
155
|
+
Nan::ThrowTypeError("Wrong number of arguments");
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (!info[0]->IsString() || !info[1]->IsString()) {
|
|
159
|
+
Nan::ThrowTypeError("Wrong arguments");
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
std::string json = FromV8String(Nan::To<v8::String>(info[0]).ToLocalChecked());
|
|
163
|
+
std::string filter = FromV8String(Nan::To<v8::String>(info[1]).ToLocalChecked());
|
|
164
|
+
|
|
165
|
+
jq_exec(json, filter, info);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
void Init(v8::Local<v8::Object> exports) {
|
|
169
|
+
v8::Local<v8::Context> context = exports->CreationContext();
|
|
170
|
+
exports->Set(context,
|
|
171
|
+
Nan::New("exec").ToLocalChecked(),
|
|
172
|
+
Nan::New<v8::FunctionTemplate>(Exec)
|
|
173
|
+
->GetFunction(context)
|
|
174
|
+
.ToLocalChecked());
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
NODE_MODULE(exec, Init)
|
package/src/binding.h
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
const jq = require('../lib');
|
|
2
|
+
|
|
3
|
+
describe('jq', () => {
|
|
4
|
+
it('should break', () => {
|
|
5
|
+
const json = { foo2: 'bar' };
|
|
6
|
+
const input = '.foo';
|
|
7
|
+
const result = jq.exec(json, input);
|
|
8
|
+
|
|
9
|
+
expect(result).toBe(null);
|
|
10
|
+
}),
|
|
11
|
+
it('should break for invalid input', () => {
|
|
12
|
+
const json = { foo2: 'bar' };
|
|
13
|
+
const input = 123;
|
|
14
|
+
const result = jq.exec(json, input);
|
|
15
|
+
|
|
16
|
+
expect(result).toBe(null);
|
|
17
|
+
}),
|
|
18
|
+
it('should break for invalid input', () => {
|
|
19
|
+
const json = { foo2: 'bar' };
|
|
20
|
+
const input = undefined;
|
|
21
|
+
const result = jq.exec(json, input);
|
|
22
|
+
|
|
23
|
+
expect(result).toBe(null);
|
|
24
|
+
}),
|
|
25
|
+
it('should break for invalid input', () => {
|
|
26
|
+
const json = { foo2: 'bar' };
|
|
27
|
+
const input = null;
|
|
28
|
+
const result = jq.exec(json, input);
|
|
29
|
+
|
|
30
|
+
expect(result).toBe(null);
|
|
31
|
+
}),
|
|
32
|
+
it('string should work', () => {
|
|
33
|
+
const json = { foo: 'bar' };
|
|
34
|
+
const input = '.foo';
|
|
35
|
+
const result = jq.exec(json, input);
|
|
36
|
+
|
|
37
|
+
expect(result).toBe('bar');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('number should work', ()=> {
|
|
41
|
+
const json = { foo: 1 };
|
|
42
|
+
const input = '.foo';
|
|
43
|
+
const result = jq.exec(json, input);
|
|
44
|
+
|
|
45
|
+
expect(result).toBe(1);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it ('should return null', () => {
|
|
49
|
+
const json = { foo: 'bar' };
|
|
50
|
+
const input = '.bar';
|
|
51
|
+
const result = jq.exec(json, input);
|
|
52
|
+
|
|
53
|
+
expect(result).toBe(null);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it ('should return array with object', () => {
|
|
57
|
+
const json = { foo: ['bar'] };
|
|
58
|
+
const input = '.foo';
|
|
59
|
+
const result = jq.exec(json, input);
|
|
60
|
+
|
|
61
|
+
expect(result[0]).toBe('bar');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it ('should return an item of an array', () => {
|
|
65
|
+
const json = { foo: ['bar'] };
|
|
66
|
+
const input = '.foo[0]';
|
|
67
|
+
const result = jq.exec(json, input);
|
|
68
|
+
|
|
69
|
+
expect(result).toBe('bar');
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it ('should return array with objects', () => {
|
|
73
|
+
const json = { foo: [{ bar: 'bar' }] };
|
|
74
|
+
const input = '.foo';
|
|
75
|
+
const result = jq.exec(json, input);
|
|
76
|
+
|
|
77
|
+
expect(result[0].bar).toBe('bar');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it ('should return boolean', () => {
|
|
81
|
+
const json = { foo: true };
|
|
82
|
+
const input = '.foo';
|
|
83
|
+
const result = jq.exec(json, input);
|
|
84
|
+
|
|
85
|
+
expect(result).toBe(true);
|
|
86
|
+
});
|
|
87
|
+
it ('should return object', () => {
|
|
88
|
+
const json = { foo: {prop1: "1"} };
|
|
89
|
+
const input = '.foo';
|
|
90
|
+
const result = jq.exec(json, input);
|
|
91
|
+
|
|
92
|
+
expect(result.prop1).toBe("1");
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it ('should return recursed obj', () => {
|
|
96
|
+
const json = { foo: {obj: { obj2: { num: 1, string: "str"} }} };
|
|
97
|
+
const input = '.foo';
|
|
98
|
+
const result = jq.exec(json, input);
|
|
99
|
+
|
|
100
|
+
expect(result.obj.obj2.num).toBe(1);
|
|
101
|
+
expect(result.obj.obj2.string).toBe("str");
|
|
102
|
+
}),
|
|
103
|
+
|
|
104
|
+
it ('should return recursed obj', () => {
|
|
105
|
+
const json = { foo: { obj: { obj2: { num: 1, string: "str", bool: true} }} };
|
|
106
|
+
const input = '.foo';
|
|
107
|
+
const result = jq.exec(json, input);
|
|
108
|
+
|
|
109
|
+
expect(result.obj.obj2.num).toBe(1);
|
|
110
|
+
expect(result.obj.obj2.string).toBe("str");
|
|
111
|
+
expect(result.obj.obj2.bool).toBe(true);
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it ('should return null on invalid json', () => {
|
|
115
|
+
const json = "foo";
|
|
116
|
+
const input = '.foo';
|
|
117
|
+
const result = jq.exec(json, input);
|
|
118
|
+
|
|
119
|
+
expect(result).toBe(undefined);
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var path = require('path');
|
|
4
|
+
|
|
5
|
+
var baseDir = path.resolve(__dirname, '../');
|
|
6
|
+
|
|
7
|
+
var isWin = /^win/.test(process.platform);
|
|
8
|
+
|
|
9
|
+
// Skip running this if we are running on a windows system
|
|
10
|
+
if (isWin) {
|
|
11
|
+
process.stderr.write('Skipping run because we are on windows\n');
|
|
12
|
+
process.exit(0);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
var childProcess = require('child_process');
|
|
16
|
+
console.log("LD_LIBRARY_PATH: " + process.env.LD_LIBRARY_PATH);
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
childProcess.execSync('./configure', {
|
|
20
|
+
cwd: baseDir,
|
|
21
|
+
stdio: [0,1,2]
|
|
22
|
+
});
|
|
23
|
+
process.exit(0);
|
|
24
|
+
} catch (e) {
|
|
25
|
+
process.stderr.write(e.message + '\n');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|