Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,24 @@ jobs:
- name: Run ts tests
run: make -C lib/nodets check

- name: Run js precross
run: make -C lib/nodejs precross

- name: Run ts precross
run: make -C lib/nodets precross

- name: Upload nodejs precross artifacts
uses: actions/upload-artifact@v7
with:
name: nodejs-precross
if-no-files-found: error
include-hidden-files: true
path: |
lib/nodejs/test/gen-nodejs
lib/nodets/test/gen-nodejs
lib/nodets/test-compiled
retention-days: 3

lib-cpp:
needs: compiler
runs-on: ubuntu-24.04
Expand Down Expand Up @@ -828,15 +846,16 @@ jobs:
- lib-python
- lib-cpp
- lib-ruby
- lib-nodejs
runs-on: ubuntu-24.04
strategy:
matrix:
# swift is currently broken and no maintainers around -> see THRIFT-5864
# rust currently broken and no maintainers around -> see THRIFT-5917
# kotlin cross test are failing -> see THRIFT-5879
server_lang: ['java', 'go', 'cpp', 'py', 'rb']
server_lang: ['java', 'go', 'cpp', 'py', 'rb', 'nodejs', 'nodets']
# we always use comma join as many client langs as possible, to reduce the number of jobs
client_lang: ['java,kotlin', 'go,cpp,py', 'rb']
client_lang: ['java,kotlin', 'go,cpp,py,nodejs,nodets', 'rb']
fail-fast: false
steps:
- uses: actions/checkout@v6
Expand Down Expand Up @@ -922,6 +941,12 @@ jobs:
name: rb-precross
path: .

- name: Download nodejs and nodets precross artifacts
uses: actions/download-artifact@v8
with:
name: nodejs-precross
path: lib

- name: Set back executable flags
run: |
chmod a+x lib/java/build/run*
Expand All @@ -936,6 +961,11 @@ jobs:
chmod a+x test/py/*.py
chmod a+x lib/rb/ext/*.so

- name: Installs for nodets and nodejs
run: |
npm install .
cd lib/nodejs/test/ && npm install .

- name: Create tmp domain socket folder
run: mkdir /tmp/v0.16

Expand Down
4 changes: 2 additions & 2 deletions LANGUAGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr
<!-- Since -----------------><td>0.6.0</td>
<!-- Build Systems ---------><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td>10.x</td><td>10.x</td>
<!-- Field types -----------><td><img src="/doc/images/cred.png" alt=""/></td>
<!-- Field types -----------><td><img src="/doc/images/cgrn.png" alt="Yes"/></td>
<!-- Low-Level Transports --><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cgrn.png" alt="Yes"/></td>
<!-- Transport Wrappers ----><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cgrn.png" alt="Yes"/></td>
Expand All @@ -253,7 +253,7 @@ Thrift's core protocol is TBinary, supported by all languages except for JavaScr
<!-- Since -----------------><td>0.12.0</td>
<!-- Build Systems ---------><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td>5.7.2</td><td></td>
<!-- Field types -----------><td><img src="/doc/images/cred.png" alt=""/></td>
<!-- Field types -----------><td><img src="/doc/images/cgrn.png" alt="Yes"/></td>
<!-- Low-Level Transports --><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cgrn.png" alt="Yes"/></td>
<!-- Transport Wrappers ----><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="/doc/images/cgrn.png" alt="Yes"/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cred.png" alt=""/></td><td><img src="/doc/images/cred.png" alt=""/></td>
Expand Down
8 changes: 4 additions & 4 deletions build/docker/ubuntu-noble/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - &
/etc/apt/sources.list.d/dart_stable.list

# node.js
RUN curl -sL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \
echo "deb https://deb.nodesource.com/node_16.x focal main" | tee /etc/apt/sources.list.d/nodesource.list
RUN curl -sL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | apt-key add - && \
echo "deb https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list

### install general dependencies
RUN apt-get update -yq && \
Expand Down Expand Up @@ -295,8 +295,8 @@ RUN apt-get install -y --no-install-recommends \
RUN apt-get install -y --no-install-recommends \
`# Static Code Analysis dependencies` \
cppcheck \
sloccount
sloccount

#RUN pip install flake8

# NOTE: this does not reduce the image size but adds an additional layer.
Expand Down
37 changes: 30 additions & 7 deletions compiler/cpp/src/thrift/generate/t_js_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ void t_js_generator::init_generator() {
string t_js_generator::js_includes() {
if (gen_node_) {
string result;

if (gen_esm_) {
result += "import { Thrift } from 'thrift';\n";
} else {
Expand All @@ -534,13 +534,16 @@ string t_js_generator::js_includes() {
}
}
if (gen_esm_) {
result += "import Int64 from 'node-int64';";
result += "import Int64 from 'node-int64';\n";
result += "import { v4 as uuid } from 'uuid';";
} else {
result += js_const_type_ + "Int64 = require('node-int64');\n";
result += js_const_type_ + "uuid = require('uuid').v4;\n";
}
return result;
}
string result = "if (typeof Int64 === 'undefined' && typeof require === 'function') {\n " + js_const_type_ + "Int64 = require('node-int64');\n}\n";
result += "if (typeof uuid === 'undefined' && typeof require === 'function') {\n " + js_const_type_ + "uuid = require('uuid').v4;\n}\n";
return result;
}

Expand All @@ -553,9 +556,14 @@ string t_js_generator::ts_includes() {
"import thrift = require('thrift');\n"
"import Thrift = thrift.Thrift;\n"
"import Q = thrift.Q;\n"
"import Int64 = require('node-int64');");
}
return string("import Int64 = require('node-int64');");
"import Int64 = require('node-int64');\n"
"import { v4 as uuid } from 'uuid';\n"
"type uuid = string;");
}
return string(
"import Int64 = require('node-int64');\n"
"import { v4 as uuid } from 'uuid';\n"
"type uuid = string;");
}

/**
Expand Down Expand Up @@ -742,6 +750,9 @@ string t_js_generator::render_const_value(t_type* type, t_const_value* value) {
case t_base_type::TYPE_STRING:
out << "'" << get_escaped_string(value) << "'";
break;
case t_base_type::TYPE_UUID:
out << "'" << value << "'";
break;
case t_base_type::TYPE_BOOL:
out << (value->get_integer() > 0 ? "true" : "false");
break;
Expand Down Expand Up @@ -2317,6 +2328,9 @@ void t_js_generator::generate_deserialize_field(ostream& out,
case t_base_type::TYPE_STRING:
out << (type->is_binary() ? "readBinary()" : "readString()");
break;
case t_base_type::TYPE_UUID:
out << "readUuid()";
break;
case t_base_type::TYPE_BOOL:
out << "readBool()";
break;
Expand Down Expand Up @@ -2503,6 +2517,9 @@ void t_js_generator::generate_serialize_field(ostream& out, t_field* tfield, str
case t_base_type::TYPE_STRING:
out << (type->is_binary() ? "writeBinary(" : "writeString(") << name << ")";
break;
case t_base_type::TYPE_UUID:
out << "writeUuid(" << name << ")";
break;
case t_base_type::TYPE_BOOL:
out << "writeBool(" << name << ")";
break;
Expand Down Expand Up @@ -2661,6 +2678,7 @@ string t_js_generator::declare_field(t_field* tfield, bool init, bool obj) {
case t_base_type::TYPE_VOID:
break;
case t_base_type::TYPE_STRING:
case t_base_type::TYPE_UUID:
case t_base_type::TYPE_BOOL:
case t_base_type::TYPE_I8:
case t_base_type::TYPE_I16:
Expand Down Expand Up @@ -2752,6 +2770,8 @@ string t_js_generator::type_to_enum(t_type* type) {
throw std::runtime_error("NO T_VOID CONSTRUCT");
case t_base_type::TYPE_STRING:
return "Thrift.Type.STRING";
case t_base_type::TYPE_UUID:
return "Thrift.Type.UUID";
case t_base_type::TYPE_BOOL:
return "Thrift.Type.BOOL";
case t_base_type::TYPE_I8:
Expand All @@ -2765,7 +2785,7 @@ string t_js_generator::type_to_enum(t_type* type) {
case t_base_type::TYPE_DOUBLE:
return "Thrift.Type.DOUBLE";
default:
throw "compiler error: unhandled type";
throw "compiler error: unhandled js type";
}
} else if (type->is_enum()) {
return "Thrift.Type.I32";
Expand Down Expand Up @@ -2798,6 +2818,9 @@ string t_js_generator::ts_get_type(t_type* type) {
case t_base_type::TYPE_STRING:
ts_type = type->is_binary() ? "Buffer" : "string";
break;
case t_base_type::TYPE_UUID:
ts_type = "uuid";
break;
case t_base_type::TYPE_BOOL:
ts_type = "boolean";
break;
Expand All @@ -2816,7 +2839,7 @@ string t_js_generator::ts_get_type(t_type* type) {
ts_type = "void";
break;
default:
throw "compiler error: unhandled type";
throw "compiler error: unhandled js type";
}
} else if (type->is_enum() || type->is_struct() || type->is_xception()) {
std::string type_name;
Expand Down
2 changes: 1 addition & 1 deletion compiler/cpp/src/thrift/generate/t_st_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ string t_st_generator::type_to_enum(t_type* type) {
case t_base_type::TYPE_DOUBLE:
return "TType double";
default:
throw "compiler error: unhandled type";
throw "compiler error: unhandled ts type";
}
Comment thread
CJCombrink marked this conversation as resolved.
} else if (type->is_enum()) {
return "TType i32";
Expand Down
7 changes: 2 additions & 5 deletions lib/nodejs/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,8 @@

# We call npm twice to work around npm issues

stubs: $(top_srcdir)/test/v0.16/ThriftTest.thrift $(top_srcdir)/test/v0.16/FuzzTestNoUuid.thrift
$(THRIFT) --gen js:node -o test/ $(top_srcdir)/test/v0.16/ThriftTest.thrift
$(THRIFT) --gen js:node -o test/fuzz/ $(top_srcdir)/test/v0.16/FuzzTestNoUuid.thrift
sed -i "s/require('thrift')/require(\"..\/..\/..\/lib\/thrift\")/" test/fuzz/gen-nodejs/FuzzTestNoUuid_types.js

stubs: $(top_srcdir)/test/ThriftTest.thrift
$(THRIFT) --gen js:node -o test/ $(top_srcdir)/test/ThriftTest.thrift

deps-root: $(top_srcdir)/package.json
$(NPM) install $(top_srcdir)/ || $(NPM) install $(top_srcdir)/
Expand Down
14 changes: 14 additions & 0 deletions lib/nodejs/lib/thrift/binary_protocol.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ var Int64 = require("node-int64");
var Thrift = require("./thrift");
var Type = Thrift.Type;

const { parse: uuidParse, stringify: uuidStringify } = require("uuid");

module.exports = TBinaryProtocol;

// JavaScript supports only numeric doubles, therefore even hex values are always signed.
Expand Down Expand Up @@ -170,6 +172,10 @@ TBinaryProtocol.prototype.writeBinary = function (arg) {
this.writeStringOrBinary("writeBinary", "binary", arg);
};

TBinaryProtocol.prototype.writeUuid = function (arg) {
this.trans.write(Buffer.from(uuidParse(arg)));
};

TBinaryProtocol.prototype.readMessageBegin = function () {
var sz = this.readI32();
var type, name, seqid;
Expand Down Expand Up @@ -302,6 +308,11 @@ TBinaryProtocol.prototype.readString = function () {
return this.trans.readString(len);
};

TBinaryProtocol.prototype.readUuid = function () {
const buf = this.trans.read(16);
return uuidStringify(new Uint8Array(buf));
};

TBinaryProtocol.prototype.getTransport = function () {
return this.trans;
};
Expand Down Expand Up @@ -329,6 +340,9 @@ TBinaryProtocol.prototype.skip = function (type) {
case Type.STRING:
this.readString();
break;
case Type.UUID:
this.readUuid();
break;
case Type.STRUCT:
this.readStructBegin();
while (true) {
Expand Down
19 changes: 19 additions & 0 deletions lib/nodejs/lib/thrift/compact_protocol.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ var Int64 = require("node-int64");
var Thrift = require("./thrift");
var Type = Thrift.Type;

const { parse: uuidParse, stringify: uuidStringify } = require("uuid");

module.exports = TCompactProtocol;

var POW_8 = Math.pow(2, 8);
Expand Down Expand Up @@ -120,6 +122,7 @@ TCompactProtocol.TYPE_SHIFT_AMOUNT = 5;
* @property {number} CT_SET - A collection type (unordered and without repeated values).
* @property {number} CT_MAP - A collection type (map/associative-array/dictionary).
* @property {number} CT_STRUCT - A multifield type.
* @property {number} CT_UUID - A UUID type.
*/
TCompactProtocol.Types = {
CT_STOP: 0x00,
Expand All @@ -135,6 +138,7 @@ TCompactProtocol.Types = {
CT_SET: 0x0a,
CT_MAP: 0x0b,
CT_STRUCT: 0x0c,
CT_UUID: 0x0d,
};

/**
Expand All @@ -158,6 +162,7 @@ TCompactProtocol.TTypeToCType = [
TCompactProtocol.Types.CT_MAP, // T_MAP
TCompactProtocol.Types.CT_SET, // T_SET
TCompactProtocol.Types.CT_LIST, // T_LIST
TCompactProtocol.Types.CT_UUID, // T_UUID
];

//
Expand Down Expand Up @@ -214,6 +219,8 @@ TCompactProtocol.prototype.getTType = function (type) {
return Type.MAP;
case TCompactProtocol.Types.CT_STRUCT:
return Type.STRUCT;
case TCompactProtocol.Types.CT_UUID:
return Type.UUID;
default:
throw new Thrift.TProtocolException(
Thrift.TProtocolExceptionType.INVALID_DATA,
Expand Down Expand Up @@ -459,6 +466,10 @@ TCompactProtocol.prototype.writeBinary = function (arg) {
this.writeStringOrBinary("writeBinary", "binary", arg);
};

TCompactProtocol.prototype.writeUuid = function (arg) {
this.trans.write(Buffer.from(uuidParse(arg)));
};

//
// Compact Protocol internal write methods
//
Expand Down Expand Up @@ -735,6 +746,11 @@ TCompactProtocol.prototype.readByte = function () {
return this.trans.readByte();
};

TCompactProtocol.prototype.readUuid = function () {
const buf = this.trans.read(16);
return uuidStringify(new Uint8Array(buf));
};

TCompactProtocol.prototype.readI16 = function () {
return this.readI32();
};
Expand Down Expand Up @@ -908,6 +924,9 @@ TCompactProtocol.prototype.skip = function (type) {
case Type.STRING:
this.readString();
break;
case Type.UUID:
this.readUuid();
break;
case Type.STRUCT:
this.readStructBegin();
while (true) {
Expand Down
8 changes: 8 additions & 0 deletions lib/nodejs/lib/thrift/header_protocol.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ THeaderProtocol.prototype.writeBinary = function (arg) {
return this.protocol.writeBinary(arg);
};

THeaderProtocol.prototype.writeUuid = function (arg) {
return this.protocol.writeUuid(arg);
};

THeaderProtocol.prototype.readMessageBegin = function () {
this.trans.readHeaders();
this.setProtocol();
Expand Down Expand Up @@ -236,6 +240,10 @@ THeaderProtocol.prototype.readBinary = function () {
return this.protocol.readBinary();
};

THeaderProtocol.prototype.readUuid = function () {
return this.protocol.readUuid();
};

THeaderProtocol.prototype.readString = function () {
return this.protocol.readString();
};
Expand Down
Loading
Loading