mirror of
https://github.com/status-im/realm-js.git
synced 2025-01-10 14:25:58 +00:00
Node.js Win32 support (#864)
* Remove the windows install check * Node.js Win32 support * Bring back the `REALM_HAVE_CONFIG` definition * Download core for Windows when building * Implement cross-platform node platform.cpp with libuv * wip * Make jasmine run quicker https://github.com/jasmine/jasmine/issues/1204 * Wait for worker process to close in AsyncTests * Cross-platform paths in tests * Normalize path separator for forward slash on Windows * MSVC exception voodoo * cross-platform uv_cwd * fix linux build * make the prepublish script cross-platform * Disable encryption tests on windows * ignore vendor/realm-node * jenkinsfile work * Only run the prepublish script for publish and pack * Jenkinsfile work * Include gyp files in package * rewrite default_realm_file_directory() * fix React Native Android build * delete all realm artifacts in remove_realm_files_from_directory * bring back build environment variables * node-pre-gyp windows * Update CHANGELOG.md
This commit is contained in:
parent
b93cfaf909
commit
db8ebd9333
1
.gitignore
vendored
1
.gitignore
vendored
@ -22,6 +22,7 @@ sync
|
||||
sync-*
|
||||
node-sync
|
||||
node-sync-*
|
||||
vendor/realm-node*
|
||||
|
||||
# sh build.sh config
|
||||
/Realm/config.mk
|
||||
|
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,3 +1,14 @@
|
||||
X.Y.Z Release notes
|
||||
=============================================================
|
||||
### Breaking changes
|
||||
* None
|
||||
|
||||
### Enhancements
|
||||
* Add support for Node.js on Windows
|
||||
|
||||
### Bug fixes
|
||||
* None
|
||||
|
||||
1.0.3 Release notes
|
||||
=============================================================
|
||||
### Breaking changes
|
||||
|
21
Jenkinsfile
vendored
21
Jenkinsfile
vendored
@ -74,7 +74,8 @@ stage('build') {
|
||||
macos_react_example_release: doMacBuild('react-example Release'),
|
||||
//android_react_tests: doAndroidBuild('react-tests-android', {
|
||||
// junit 'tests/react-test-app/tests.xml'
|
||||
//})
|
||||
//}),
|
||||
windows_node: doWindowsBuild()
|
||||
)
|
||||
}
|
||||
|
||||
@ -201,3 +202,21 @@ def doReactBuild(target, postStep = null) {
|
||||
}
|
||||
}
|
||||
|
||||
def doWindowsBuild() {
|
||||
return {
|
||||
node('windows') {
|
||||
unstash 'source'
|
||||
try {
|
||||
bat 'npm install --build-from-source'
|
||||
dir('tests') {
|
||||
bat 'npm install'
|
||||
bat 'npm run test-nosync'
|
||||
junit 'junitresults-*.xml'
|
||||
}
|
||||
} finally {
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
"realm_download_binaries%": "1"
|
||||
},
|
||||
"includes": [
|
||||
"src/node/gyp/target_defaults.gypi",
|
||||
"src/node/gyp/realm.gyp"
|
||||
"target_defaults.gypi",
|
||||
"realm.gyp"
|
||||
],
|
||||
"targets": [
|
||||
{
|
||||
@ -66,6 +66,11 @@
|
||||
"src/object-store/src/util/format.cpp",
|
||||
],
|
||||
"conditions": [
|
||||
["OS=='win'", {
|
||||
"sources": [
|
||||
"src/object-store/src/impl/windows/external_commit_helper.cpp",
|
||||
]
|
||||
}],
|
||||
["OS=='linux'", {
|
||||
"sources": [
|
||||
"src/object-store/src/impl/epoll/external_commit_helper.cpp",
|
||||
|
@ -39,6 +39,8 @@
|
||||
"tests",
|
||||
"vendor",
|
||||
"binding.gyp",
|
||||
"realm.gyp",
|
||||
"target_defaults.gypi",
|
||||
"dependencies.list"
|
||||
],
|
||||
"scripts": {
|
||||
@ -49,10 +51,12 @@
|
||||
"jsdoc": "rm -rf docs/output && jsdoc -c docs/conf.json",
|
||||
"lint": "eslint",
|
||||
"test": "scripts/test.sh",
|
||||
"install": "node scripts/install.js",
|
||||
"prepublish": "scripts/prepublish.sh"
|
||||
"install": "node-pre-gyp install --fallback-to-build",
|
||||
"prepublish": "node scripts/prepublish.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"extract-zip": "^1.6.0",
|
||||
"ini": "^1.3.4",
|
||||
"nan": "^2.3.3",
|
||||
"node-fetch": "^1.6.3",
|
||||
"node-pre-gyp": "^0.6.30",
|
||||
|
143
realm.gyp
Normal file
143
realm.gyp
Normal file
@ -0,0 +1,143 @@
|
||||
{
|
||||
"variables": {
|
||||
"use_realm_debug%": "<!(node -p \"'REALMJS_USE_DEBUG_CORE' in process.env ? 1 : 0\")"
|
||||
},
|
||||
"conditions": [
|
||||
["OS=='mac'", {
|
||||
"variables": {
|
||||
"realm_enable_sync%": "1"
|
||||
}
|
||||
}, {
|
||||
"variables": {
|
||||
"realm_enable_sync%": "0"
|
||||
}
|
||||
}],
|
||||
["OS=='win'", {
|
||||
"conditions": [
|
||||
["target_arch == 'ia32'", {
|
||||
"variables": {
|
||||
"realm_library_suffix": "-x86"
|
||||
}
|
||||
}, {
|
||||
"variables": {
|
||||
"realm_library_suffix": "-<(target_arch)"
|
||||
}
|
||||
}]
|
||||
]
|
||||
}, {
|
||||
"variables": {
|
||||
"realm_library_suffix": "-node"
|
||||
}
|
||||
}]
|
||||
],
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "realm-core",
|
||||
"type": "none",
|
||||
"direct_dependent_settings": {
|
||||
"conditions": [
|
||||
["use_realm_debug", {
|
||||
"defines": [ "REALM_DEBUG=1" ],
|
||||
"libraries": [ "-lrealm<(realm_library_suffix)-dbg" ]
|
||||
}, {
|
||||
"libraries": [ "-lrealm<(realm_library_suffix)" ]
|
||||
}]
|
||||
]
|
||||
},
|
||||
"all_dependent_settings": {
|
||||
"defines": [ "REALM_PLATFORM_NODE=1", "REALM_ENABLE_SYNC=<(realm_enable_sync)" ]
|
||||
},
|
||||
"variables": {
|
||||
"prefix": "<!(node -p \"process.env.REALM_CORE_PREFIX || String()\")"
|
||||
},
|
||||
"conditions": [
|
||||
["prefix!=''", {
|
||||
"all_dependent_settings": {
|
||||
"include_dirs": [ "<(prefix)/src" ],
|
||||
},
|
||||
"direct_dependent_settings": {
|
||||
"library_dirs": [ "<(prefix)/src/realm" ]
|
||||
}
|
||||
}, {
|
||||
"dependencies": [ "vendored-realm" ]
|
||||
}],
|
||||
["OS=='win'", {
|
||||
"all_dependent_settings": {
|
||||
"defines": [ "PTW32_STATIC_LIB" ]
|
||||
}
|
||||
}, {
|
||||
"all_dependent_settings": {
|
||||
"defines": [ "REALM_HAVE_CONFIG" ]
|
||||
}
|
||||
}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"target_name": "realm-sync",
|
||||
"type": "none",
|
||||
"dependencies": [ "realm-core" ], # sync headers include core headers
|
||||
"direct_dependent_settings": {
|
||||
"conditions": [
|
||||
["use_realm_debug", {
|
||||
"libraries": [ "-lrealm-sync<(realm_library_suffix)-dbg" ]
|
||||
}, {
|
||||
"libraries": [ "-lrealm-sync<(realm_library_suffix)" ]
|
||||
}]
|
||||
]
|
||||
},
|
||||
"export_dependent_settings": [ "realm-core" ], # depending on sync is tantamount to depending on core
|
||||
"variables": {
|
||||
"prefix": "<!(node -p \"process.env.REALM_SYNC_PREFIX || String()\")"
|
||||
},
|
||||
"conditions": [
|
||||
["prefix!=''", {
|
||||
"all_dependent_settings": {
|
||||
"include_dirs": [ "<(prefix)/src" ],
|
||||
},
|
||||
"direct_dependent_settings": {
|
||||
"library_dirs": [ "<(prefix)/src/realm" ]
|
||||
}
|
||||
}, {
|
||||
"dependencies": [ "vendored-realm" ]
|
||||
}]
|
||||
],
|
||||
},
|
||||
{
|
||||
"variables": {
|
||||
"vendor_dir%": "<(module_root_dir)/vendor"
|
||||
},
|
||||
"target_name": "vendored-realm",
|
||||
"type": "none",
|
||||
"all_dependent_settings": {
|
||||
"include_dirs": [ "<(module_root_dir)/vendor/realm-node/include" ],
|
||||
"library_dirs": [
|
||||
"<(module_root_dir)/vendor/realm-node/",
|
||||
"<(module_root_dir)/vendor/realm-node/lib",
|
||||
"<(module_root_dir)/vendor/realm-node/osx"
|
||||
]
|
||||
},
|
||||
"conditions": [
|
||||
["realm_download_binaries and OS=='win'", {
|
||||
"actions": [
|
||||
{
|
||||
"action_name": "download-realm",
|
||||
"inputs": [ "<(module_root_dir)/scripts/download-realm.js" ],
|
||||
"outputs": [ "<(module_root_dir)/vendor/realm-node" ],
|
||||
"action": [ "node", "<(module_root_dir)/scripts/download-realm.js", "node", "<(use_realm_debug)" ]
|
||||
}
|
||||
]
|
||||
}],
|
||||
["realm_download_binaries and OS!='win'", {
|
||||
"actions": [
|
||||
{
|
||||
"action_name": "download-realm",
|
||||
"inputs": [ ],
|
||||
"outputs": [ "<(module_root_dir)/vendor/realm-node" ],
|
||||
"action": [ "<(module_root_dir)/scripts/download-core.sh", "node", "<(realm_enable_sync)" ]
|
||||
}
|
||||
]
|
||||
}]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
29
scripts/build-node-pre-gyp.ps1
Normal file
29
scripts/build-node-pre-gyp.ps1
Normal file
@ -0,0 +1,29 @@
|
||||
<#
|
||||
Copyright 2016 Realm Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
#>
|
||||
|
||||
Push-Location $PSScriptRoot\..
|
||||
New-Item .\out -ItemType "directory"
|
||||
|
||||
npm install --ignore-scripts
|
||||
|
||||
foreach ($arch in "ia32", "x64") {
|
||||
foreach ($version in "4.0.0", "5.0.0", "6.0.0", "7.0.0") {
|
||||
Remove-Item .\build, .\compiled -Recurse -Force -ErrorAction Ignore
|
||||
.\node_modules\node-pre-gyp\bin\node-pre-gyp.cmd rebuild --target_arch=$arch --target=$version
|
||||
.\node_modules\node-pre-gyp\bin\node-pre-gyp.cmd package --target_arch=$arch --target=$version
|
||||
Copy-Item .\build\stage\node-pre-gyp\*.tar.gz -Destination .\out
|
||||
}
|
||||
}
|
@ -20,8 +20,8 @@ fi
|
||||
# The 'node' argument will result in realm-node build being downloaded.
|
||||
if [ "$1" = 'node' ]; then
|
||||
ENABLE_SYNC="$2"
|
||||
CORE_DIR="core-node"
|
||||
SYNC_DIR='node-sync'
|
||||
CORE_DIR="realm-node"
|
||||
SYNC_DIR='realm-node'
|
||||
|
||||
if [ "$(uname)" = 'Darwin' ]; then
|
||||
PLATFORM_TAG="node-osx-"
|
||||
|
67
scripts/download-realm.js
Normal file
67
scripts/download-realm.js
Normal file
@ -0,0 +1,67 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const fetch = require('node-fetch');
|
||||
const ini = require('ini').parse;
|
||||
const unzip = require('extract-zip');
|
||||
|
||||
function download(url, destination) {
|
||||
return fetch(url).then((response) => {
|
||||
if (response.status !== 200) {
|
||||
throw new Error(`Error downloading ${url} - received status ${response.status} ${response.statusText}`);
|
||||
} else if (response.headers.get('content-type') !== 'application/zip') {
|
||||
throw new Error(`Unexpected response content type - ${response.headers.get('content-type')}`);
|
||||
} else {
|
||||
return new Promise((resolve) => {
|
||||
const file = fs.createWriteStream(destination);
|
||||
response.body.pipe(file)
|
||||
.on('finish', () => {
|
||||
file.close(resolve);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function extract(archive, destination) {
|
||||
return new Promise((resolve, reject) => {
|
||||
unzip(archive, { dir: destination }, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const dependencies = ini(fs.readFileSync(path.resolve(__dirname, '../dependencies.list'), 'utf8'));
|
||||
const coreArchive = `realm-core-windows-${dependencies.REALM_CORE_VERSION}.zip`;
|
||||
const coreUrl = `https://static.realm.io/downloads/core/${coreArchive}`;
|
||||
const vendorDir = path.resolve(__dirname, '../vendor');
|
||||
const downloadedCoreArchive = path.resolve(vendorDir, coreArchive);
|
||||
const realmDir = path.resolve(vendorDir, 'realm-node');
|
||||
|
||||
if (!fs.existsSync(realmDir)) {
|
||||
const downloadTask = fs.existsSync(downloadedCoreArchive) ? Promise.resolve() : download(coreUrl, downloadedCoreArchive);
|
||||
downloadTask.then(() => extract(downloadedCoreArchive, realmDir));
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
'use strict';
|
||||
|
||||
var spawn = require('child_process').spawn;
|
||||
|
||||
var isReactNative = false;
|
||||
try {
|
||||
require.resolve('react-native');
|
||||
// If the above opeation didn't throw, this project has react native as a dependency.
|
||||
isReactNative = true;
|
||||
} catch(e) {}
|
||||
|
||||
// Not a React Native install. Must be either Node or Electron.
|
||||
var isNode = !isReactNative;
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
if (isNode) {
|
||||
console.error('ERROR: Realm is not yet supported for Node on Windows');
|
||||
process.exit(-1);
|
||||
} else {
|
||||
console.warn('NOTE: Realm is not supported for Node on Windows, so you will not be able to run unit tests that rely on Realm with a node-based runner.');
|
||||
}
|
||||
} else {
|
||||
// Execute "node-pre-gyp install --fallback-to-build
|
||||
var pregyp = spawn('node-pre-gyp', ['install', '--fallback-to-build']);
|
||||
pregyp.stdout.on('data', function (data) { console.log(data.toString()); });
|
||||
pregyp.stderr.on('data', function (data) { console.error(data.toString()); });
|
||||
pregyp.on('exit', function (code) { process.exit(code); });
|
||||
}
|
44
scripts/prepublish.js
Normal file
44
scripts/prepublish.js
Normal file
@ -0,0 +1,44 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2016 Realm Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const exec = require('child_process').execFileSync;
|
||||
|
||||
const dependencies = ini(fs.readFileSync(path.resolve(__dirname, '../dependencies.list'), 'utf8'));
|
||||
console.log(`Core version: ${dependencies.REALM_CORE_VERSION}`);
|
||||
console.log(`Sync version: ${dependencies.REALM_SYNC_VERSION}`);
|
||||
|
||||
if ('REALM_BUILD_ANDROID' in process.env) {
|
||||
const gradlew = process.platform === 'win32' ? 'gradlew.bat' : 'gradlew';
|
||||
const androidPath = path.resolve(__dirname, '../react-native/android');
|
||||
|
||||
exec(`${androidPath}/${gradlew}`, ['publishAndroid', '-PbuildWithSync=true'], { cwd: androidPath, stdio: 'inherit' });
|
||||
}
|
||||
|
||||
function ini(string) {
|
||||
const result = Object.create(null);
|
||||
for (const line of string.split(/\r?\n/)) {
|
||||
const parts = line.split('=');
|
||||
result[parts[0]] = parts[1];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
export REALM_CORE_VERSION=$(./scripts/download-core.sh --version)
|
||||
echo "Core Version: $REALM_CORE_VERSION"
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
if [ -n "$REALM_BUILD_ANDROID" ]; then
|
||||
(cd react-native/android && ./gradlew publishAndroid -PbuildWithSync=true)
|
||||
fi
|
@ -35,7 +35,7 @@ namespace js {
|
||||
template<typename T>
|
||||
class List : public realm::List {
|
||||
public:
|
||||
List(std::shared_ptr<Realm> r, const ObjectSchema& s, LinkViewRef l) noexcept : realm::List(r, l) {}
|
||||
List(std::shared_ptr<realm::Realm> r, const ObjectSchema& s, LinkViewRef l) noexcept : realm::List(r, l) {}
|
||||
List(const realm::List &l) : realm::List(l) {}
|
||||
|
||||
std::vector<std::pair<Protected<typename T::Function>, NotificationToken>> m_notification_tokens;
|
||||
|
@ -30,8 +30,14 @@ namespace js {
|
||||
static std::string s_default_path = "";
|
||||
|
||||
std::string default_path() {
|
||||
if (s_default_path.size() == 0) {
|
||||
s_default_path = realm::default_realm_file_directory() + "/default.realm";
|
||||
if (s_default_path.empty()) {
|
||||
s_default_path = realm::default_realm_file_directory() +
|
||||
#if defined(WIN32) && WIN32
|
||||
'\\'
|
||||
#else
|
||||
'/'
|
||||
#endif
|
||||
+ "default.realm";
|
||||
}
|
||||
return s_default_path;
|
||||
}
|
||||
|
@ -262,9 +262,16 @@ public:
|
||||
}
|
||||
|
||||
static std::string normalize_path(std::string path) {
|
||||
if (path.size() && path[0] != '/' && path[0] != '.') {
|
||||
return default_realm_file_directory() + "/" + path;
|
||||
#if defined(WIN32) && WIN32
|
||||
if (path.size() > 1 && path[0] != '\\' && path[1] != ':') {
|
||||
path = default_realm_file_directory() + "\\" + path;
|
||||
}
|
||||
std::replace(path.begin(), path.end(), '/', '\\');
|
||||
#else
|
||||
if (path.size() && path[0] != '/' && path[0] != '.') {
|
||||
path = default_realm_file_directory() + "/" + path;
|
||||
}
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
};
|
||||
@ -428,7 +435,7 @@ void RealmClass<T>::constructor(ContextType ctx, ObjectType this_object, size_t
|
||||
template<typename T>
|
||||
SharedRealm RealmClass<T>::create_shared_realm(ContextType ctx, realm::Realm::Config config, bool schema_updated,
|
||||
ObjectDefaultsMap && defaults, ConstructorMap && constructors) {
|
||||
config.execution_context = reinterpret_cast<AbstractExecutionContextID>(Context<T>::get_execution_context_id(ctx));
|
||||
config.execution_context = Context<T>::get_execution_context_id(ctx);
|
||||
|
||||
SharedRealm realm = realm::Realm::get_shared_realm(config);
|
||||
|
||||
|
@ -195,7 +195,7 @@ struct Object {
|
||||
template<typename P>
|
||||
static ValueType validated_get_property(ContextType ctx, const ObjectType &object, const P &property, const char *message = nullptr) {
|
||||
if (!has_property(ctx, object, property)) {
|
||||
throw std::out_of_range(message ?: "Object missing expected property: " + util::to_string(property));
|
||||
throw std::out_of_range(message ? message : "Object missing expected property: " + util::to_string(property));
|
||||
}
|
||||
return get_property(ctx, object, property);
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ template<typename T>
|
||||
class RealmDelegate;
|
||||
|
||||
template<typename T>
|
||||
static inline RealmDelegate<T> *get_delegate(Realm *realm) {
|
||||
static inline RealmDelegate<T> *get_delegate(realm::Realm *realm) {
|
||||
return static_cast<RealmDelegate<T> *>(realm->m_binding_context.get());
|
||||
}
|
||||
|
||||
@ -59,19 +59,19 @@ static inline uint32_t validated_positive_index(std::string string) {
|
||||
|
||||
static inline void validate_argument_count(size_t count, size_t expected, const char *message = nullptr) {
|
||||
if (count != expected) {
|
||||
throw std::invalid_argument(message ?: "Invalid arguments");
|
||||
throw std::invalid_argument(message ? message : "Invalid arguments");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void validate_argument_count(size_t count, size_t min, size_t max, const char *message = nullptr) {
|
||||
if (count < min || count > max) {
|
||||
throw std::invalid_argument(message ?: "Invalid arguments");
|
||||
throw std::invalid_argument(message ? message : "Invalid arguments");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void validate_argument_count_at_least(size_t count, size_t expected, const char *message = nullptr) {
|
||||
if (count < expected) {
|
||||
throw std::invalid_argument(message ?: "Invalid arguments");
|
||||
throw std::invalid_argument(message ? message : "Invalid arguments");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,111 +0,0 @@
|
||||
{
|
||||
"variables": {
|
||||
"use_realm_debug": "<!(echo $REALMJS_USE_DEBUG_CORE)"
|
||||
},
|
||||
"conditions": [
|
||||
["OS=='mac'", {
|
||||
"variables": {
|
||||
"realm_enable_sync%": "1"
|
||||
}
|
||||
}, {
|
||||
"variables": {
|
||||
"realm_enable_sync%": "0"
|
||||
}
|
||||
}]
|
||||
],
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "realm-core",
|
||||
"type": "none",
|
||||
"direct_dependent_settings": {
|
||||
"conditions": [
|
||||
["use_realm_debug!=''", {
|
||||
"libraries": [ "-lrealm-node-dbg" ],
|
||||
"defines": [ "REALM_DEBUG=1" ]
|
||||
}, {
|
||||
"libraries": [ "-lrealm-node" ]
|
||||
}]
|
||||
]
|
||||
},
|
||||
"all_dependent_settings": {
|
||||
"defines": [ "REALM_HAVE_CONFIG", "REALM_PLATFORM_NODE=1", "REALM_ENABLE_SYNC=<(realm_enable_sync)" ]
|
||||
},
|
||||
"variables": {
|
||||
"prefix": "<!(echo $REALM_CORE_PREFIX)"
|
||||
},
|
||||
"conditions": [
|
||||
["prefix!=''", {
|
||||
"all_dependent_settings": {
|
||||
"include_dirs": [ "<(prefix)/src" ],
|
||||
},
|
||||
"direct_dependent_settings": {
|
||||
"library_dirs": [ "<(prefix)/src/realm" ]
|
||||
}
|
||||
}, {
|
||||
"dependencies": [ "vendored-realm" ]
|
||||
}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"target_name": "realm-sync",
|
||||
"type": "none",
|
||||
"dependencies": [ "realm-core" ], # sync headers include core headers
|
||||
"direct_dependent_settings": {
|
||||
"conditions": [
|
||||
["use_realm_debug!=''", {
|
||||
"libraries": [ "-lrealm-sync-node-dbg" ]
|
||||
}, {
|
||||
"libraries": [ "-lrealm-sync-node" ]
|
||||
}]
|
||||
]
|
||||
},
|
||||
"export_dependent_settings": [ "realm-core" ], # depending on sync is tantamount to depending on core
|
||||
"variables": {
|
||||
"prefix": "<!(echo $REALM_SYNC_PREFIX)"
|
||||
},
|
||||
"conditions": [
|
||||
["prefix!=''", {
|
||||
"all_dependent_settings": {
|
||||
"include_dirs": [ "<(prefix)/src" ],
|
||||
},
|
||||
"direct_dependent_settings": {
|
||||
"library_dirs": [ "<(prefix)/src/realm" ]
|
||||
}
|
||||
}, {
|
||||
"dependencies": [ "vendored-realm" ]
|
||||
}]
|
||||
],
|
||||
},
|
||||
{
|
||||
"variables": {
|
||||
"vendor_dir%": "<(module_root_dir)/vendor",
|
||||
},
|
||||
"target_name": "vendored-realm",
|
||||
"type": "none",
|
||||
"conditions": [
|
||||
["realm_enable_sync", {
|
||||
"all_dependent_settings": {
|
||||
"include_dirs": [ "<(module_root_dir)/vendor/node-sync/include" ],
|
||||
"library_dirs": [ "<(module_root_dir)/vendor/node-sync/osx" ]
|
||||
}
|
||||
}, {
|
||||
"all_dependent_settings": {
|
||||
"include_dirs": [ "<(module_root_dir)/vendor/core-node/include" ],
|
||||
"library_dirs": [ "<(module_root_dir)/vendor/core-node" ]
|
||||
},
|
||||
|
||||
}],
|
||||
["realm_download_binaries", {
|
||||
"actions": [
|
||||
{
|
||||
"action_name": "download-realm",
|
||||
"inputs": [ ],
|
||||
"outputs": [ "<(module_root_dir)/vendor/core-node" ],
|
||||
"action": [ "<(module_root_dir)/scripts/download-core.sh", "node", "<(realm_enable_sync)" ]
|
||||
}
|
||||
]
|
||||
}]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -182,12 +182,12 @@ inline v8::Local<v8::FunctionTemplate> ObjectWrap<ClassType>::create_template()
|
||||
|
||||
if (s_class.index_accessor.getter) {
|
||||
auto &index_accessor = s_class.index_accessor;
|
||||
instance_tpl->SetIndexedPropertyHandler(index_accessor.getter, index_accessor.setter ?: set_readonly_index, 0, 0, get_indexes);
|
||||
instance_tpl->SetIndexedPropertyHandler(index_accessor.getter, index_accessor.setter ? index_accessor.setter : set_readonly_index, 0, 0, get_indexes);
|
||||
}
|
||||
if (s_class.string_accessor.getter || s_class.index_accessor.getter || s_class.index_accessor.setter) {
|
||||
// Use our own wrapper for the setter since we want to throw for negative indices.
|
||||
auto &string_accessor = s_class.string_accessor;
|
||||
instance_tpl->SetNamedPropertyHandler(string_accessor.getter ?: get_nonexistent_property, set_property, 0, 0, string_accessor.enumerator);
|
||||
instance_tpl->SetNamedPropertyHandler(string_accessor.getter ? string_accessor.getter : get_nonexistent_property, set_property, 0, 0, string_accessor.enumerator);
|
||||
}
|
||||
|
||||
return scope.Escape(tpl);
|
||||
@ -219,7 +219,7 @@ inline void ObjectWrap<ClassType>::setup_property(v8::Local<TargetType> target,
|
||||
v8::Local<v8::String> prop_name = Nan::New(name).ToLocalChecked();
|
||||
v8::PropertyAttribute attributes = v8::PropertyAttribute(v8::DontEnum | v8::DontDelete);
|
||||
|
||||
target->SetAccessor(prop_name, property.getter, property.setter ?: set_readonly_property, v8::Local<v8::Value>(), v8::DEFAULT, attributes);
|
||||
target->SetAccessor(prop_name, property.getter, property.setter ? property.setter : set_readonly_property, v8::Local<v8::Value>(), v8::DEFAULT, attributes);
|
||||
}
|
||||
|
||||
template<typename ClassType>
|
||||
|
@ -16,21 +16,47 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <system_error>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <uv.h>
|
||||
|
||||
#include "../platform.hpp"
|
||||
|
||||
namespace realm {
|
||||
|
||||
class UVException : public std::runtime_error {
|
||||
public:
|
||||
UVException(uv_errno_t error)
|
||||
: std::runtime_error(uv_strerror(error))
|
||||
, m_error(error)
|
||||
{ }
|
||||
|
||||
const uv_errno_t m_error;
|
||||
};
|
||||
|
||||
struct FileSystemRequest : uv_fs_t {
|
||||
~FileSystemRequest() {
|
||||
uv_fs_req_cleanup(this);
|
||||
}
|
||||
};
|
||||
|
||||
// taken from Node.js: function Cwd in node.cc
|
||||
std::string default_realm_file_directory()
|
||||
{
|
||||
// Relative paths should always be relative to the current working directory.
|
||||
return ".";
|
||||
#ifdef _WIN32
|
||||
/* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
|
||||
char buf[MAX_PATH * 4];
|
||||
#else
|
||||
char buf[PATH_MAX];
|
||||
#endif
|
||||
|
||||
size_t cwd_len = sizeof(buf);
|
||||
int err = uv_cwd(buf, &cwd_len);
|
||||
if (err) {
|
||||
throw UVException(static_cast<uv_errno_t>(err));
|
||||
}
|
||||
|
||||
return std::string(buf, cwd_len);
|
||||
}
|
||||
|
||||
void ensure_directory_exists_for_file(const std::string &file_path)
|
||||
@ -45,8 +71,9 @@ void ensure_directory_exists_for_file(const std::string &file_path)
|
||||
}
|
||||
|
||||
std::string dir_path = file_path.substr(0, pos++);
|
||||
if (mkdir(dir_path.c_str(), 0755) != 0 && errno != EEXIST) {
|
||||
throw std::system_error(errno, std::system_category());
|
||||
FileSystemRequest req;
|
||||
if (uv_fs_mkdir(uv_default_loop(), &req, dir_path.c_str(), 0755, nullptr) < 0 && req.result != UV_EEXIST) {
|
||||
throw UVException(static_cast<uv_errno_t>(req.result));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -56,10 +83,55 @@ void copy_bundled_realm_files()
|
||||
throw std::runtime_error("Realm for Node does not support this method.");
|
||||
}
|
||||
|
||||
inline bool ends_with(const std::string& str, const std::string& suffix) {
|
||||
return str.size() > suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
|
||||
}
|
||||
|
||||
void remove_realm_files_from_directory(const std::string &dir_path)
|
||||
{
|
||||
std::string delete_realms = "rm -rf '" + dir_path + "'/*.realm*";
|
||||
system(delete_realms.c_str());
|
||||
FileSystemRequest scandir_req;
|
||||
if (uv_fs_scandir(uv_default_loop(), &scandir_req, dir_path.c_str(), 0, nullptr) < 0) {
|
||||
throw UVException(static_cast<uv_errno_t>(scandir_req.result));
|
||||
}
|
||||
|
||||
uv_dirent_t entry;
|
||||
while (uv_fs_scandir_next(&scandir_req, &entry) != UV_EOF) {
|
||||
std::string path(dir_path + '/' + entry.name);
|
||||
|
||||
if (entry.type == UV_DIRENT_DIR) {
|
||||
static std::string realm_management_extension(".realm.management");
|
||||
if (ends_with(path, realm_management_extension)) {
|
||||
uv_dirent_t management_entry;
|
||||
FileSystemRequest management_scandir_req;
|
||||
if (uv_fs_scandir(uv_default_loop(), &management_scandir_req, path.c_str(), 0, nullptr) < 0) {
|
||||
throw UVException(static_cast<uv_errno_t>(scandir_req.result));
|
||||
}
|
||||
|
||||
while (uv_fs_scandir_next(&management_scandir_req, &management_entry) != UV_EOF) {
|
||||
std::string management_entry_path = path + '/' + management_entry.name;
|
||||
FileSystemRequest delete_req;
|
||||
if (uv_fs_unlink(uv_default_loop(), &delete_req, management_entry_path.c_str(), nullptr) != 0) {
|
||||
throw UVException(static_cast<uv_errno_t>(delete_req.result));
|
||||
}
|
||||
}
|
||||
|
||||
FileSystemRequest management_rmdir_req;
|
||||
if (uv_fs_rmdir(uv_default_loop(), &management_rmdir_req, path.c_str(), nullptr)) {
|
||||
throw UVException(static_cast<uv_errno_t>(management_rmdir_req.result));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
static std::string realm_extension(".realm");
|
||||
static std::string realm_note_extension(".realm.note");
|
||||
static std::string realm_lock_extension(".realm.lock");
|
||||
if (ends_with(path, realm_extension) || ends_with(path, realm_note_extension) || ends_with(path, realm_lock_extension)) {
|
||||
FileSystemRequest delete_req;
|
||||
if (uv_fs_unlink(uv_default_loop(), &delete_req, path.c_str(), nullptr) != 0) {
|
||||
throw UVException(static_cast<uv_errno_t>(delete_req.result));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // realm
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 5a00a269ffcfbcc4c27b40a6dcf761f9b54fcc02
|
||||
Subproject commit 2f47170b380fa3ee50d2198cfc56940966c3aa1e
|
@ -24,6 +24,9 @@
|
||||
"<!(node -e \"require('nan')\")"
|
||||
],
|
||||
"conditions": [
|
||||
["OS=='win'", {
|
||||
"defines": [ "_UNICODE", "UNICODE", "WIN32=1", "_HAS_EXCEPTIONS=1" ]
|
||||
}],
|
||||
["OS=='mac'", {
|
||||
"xcode_settings": {
|
||||
"CLANG_CXX_LANGUAGE_STANDARD": "c++14",
|
||||
@ -35,6 +38,31 @@
|
||||
"WARNING_CFLAGS": [ "<@(warning-flags)" ]
|
||||
}
|
||||
}]
|
||||
]
|
||||
],
|
||||
# windows stuff
|
||||
"configurations": {
|
||||
"Debug": {
|
||||
"msvs_settings": {
|
||||
"VCCLCompilerTool": {
|
||||
"RuntimeTypeInfo": "true",
|
||||
"AdditionalOptions": [ "/MDd" ]
|
||||
},
|
||||
}
|
||||
},
|
||||
"Release": {
|
||||
"msvs_settings": {
|
||||
"VCCLCompilerTool": {
|
||||
"RuntimeTypeInfo": "true",
|
||||
"AdditionalOptions": [ "/MD" ]
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
"msvs_settings": {
|
||||
"VCCLCompilerTool": {
|
||||
"ExceptionHandling": 1
|
||||
}
|
||||
},
|
||||
"msvs_disabled_warnings": [ 4068, 4101, 4244, 4996 ],
|
||||
}
|
||||
}
|
@ -36,9 +36,9 @@ function createNotificationTest(config, getObservable, addListener, removeListen
|
||||
reject(new Error('Timed out waiting for change notification'));
|
||||
}, 5000);
|
||||
|
||||
let cleanup = () => {
|
||||
let cleanup = (cb) => {
|
||||
clearTimeout(timer);
|
||||
worker.terminate();
|
||||
worker.terminate(cb);
|
||||
};
|
||||
|
||||
var count = 0;
|
||||
@ -49,17 +49,17 @@ function createNotificationTest(config, getObservable, addListener, removeListen
|
||||
|
||||
worker.onmessage = (message) => {
|
||||
if (message.error) {
|
||||
reject(message.error);
|
||||
cleanup();
|
||||
cleanup(() => reject(message.error));
|
||||
}
|
||||
else if (message.result == 'resolve') {
|
||||
if (count != expectedCount) {
|
||||
cleanup(() => {
|
||||
if (count !== expectedCount) {
|
||||
reject('Notification count ' + count + ' not equal to expected count ' + expectedCount);
|
||||
}
|
||||
else {
|
||||
resolve();
|
||||
}
|
||||
cleanup();
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (message.result == 'removeListener') {
|
||||
|
@ -56,4 +56,17 @@ module.exports = {
|
||||
realm = new Realm({schema: [Schemas.TestObject], encryptionKey: key});
|
||||
TestCase.assertEqual(realm.objects('TestObject').length, 1);
|
||||
},
|
||||
testRealmSchemaVersion: function() {
|
||||
var encryptionKey = new Int8Array(64);
|
||||
var realm = new Realm({schema: [], schemaVersion: 3, path: 'encrypted.realm', encryptionKey: encryptionKey});
|
||||
TestCase.assertEqual(realm.schemaVersion, 3);
|
||||
TestCase.assertEqual(Realm.schemaVersion('encrypted.realm', encryptionKey), 3);
|
||||
|
||||
TestCase.assertThrows(function() {
|
||||
Realm.schemaVersion('encrypted.realm', encryptionKey, 'extra');
|
||||
});
|
||||
TestCase.assertThrows(function() {
|
||||
Realm.schemaVersion('encrypted.realm', 'asdf');
|
||||
});
|
||||
},
|
||||
};
|
||||
|
@ -26,10 +26,14 @@ var TESTS = {
|
||||
RealmTests: require('./realm-tests'),
|
||||
ResultsTests: require('./results-tests'),
|
||||
QueryTests: require('./query-tests'),
|
||||
EncryptionTests: require('./encryption-tests'),
|
||||
MigrationTests: require('./migration-tests')
|
||||
};
|
||||
|
||||
// encryption is not supported on windows
|
||||
if (!(typeof process === 'object' && process.platform === 'win32')) {
|
||||
TESTS.EncryptionTests = require('./encryption-tests');
|
||||
}
|
||||
|
||||
// If sync is enabled, run the user tests
|
||||
if (Realm.Sync) {
|
||||
TESTS.UserTests = require('./user-tests');
|
||||
|
@ -22,6 +22,11 @@ var Realm = require('realm');
|
||||
var TestCase = require('./asserts');
|
||||
var schemas = require('./schemas');
|
||||
|
||||
let pathSeparator = '/';
|
||||
if (typeof process === 'object' && process.platform === 'win32') {
|
||||
pathSeparator = '\\';
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
testRealmConstructor: function() {
|
||||
var realm = new Realm({schema: []});
|
||||
@ -45,7 +50,7 @@ module.exports = {
|
||||
var defaultRealm2 = new Realm();
|
||||
TestCase.assertEqual(defaultRealm2.path, Realm.defaultPath);
|
||||
|
||||
var defaultDir = Realm.defaultPath.substring(0, Realm.defaultPath.lastIndexOf("/") + 1)
|
||||
var defaultDir = Realm.defaultPath.substring(0, Realm.defaultPath.lastIndexOf(pathSeparator) + 1)
|
||||
var testPath = 'test1.realm';
|
||||
var realm = new Realm({schema: [], path: testPath});
|
||||
TestCase.assertEqual(realm.path, defaultDir + testPath);
|
||||
@ -150,7 +155,7 @@ module.exports = {
|
||||
TestCase.assertEqual(defaultRealm.path, Realm.defaultPath);
|
||||
|
||||
try {
|
||||
var newPath = Realm.defaultPath.substring(0, defaultPath.lastIndexOf('/') + 1) + 'default2.realm';
|
||||
var newPath = Realm.defaultPath.substring(0, defaultPath.lastIndexOf(pathSeparator) + 1) + 'default2.realm';
|
||||
Realm.defaultPath = newPath;
|
||||
defaultRealm = new Realm({schema: []});
|
||||
TestCase.assertEqual(defaultRealm.path, newPath, "should use updated default realm path");
|
||||
@ -170,18 +175,6 @@ module.exports = {
|
||||
realm = new Realm({schema: [], schemaVersion: 2, path: 'another.realm'});
|
||||
TestCase.assertEqual(realm.schemaVersion, 2);
|
||||
TestCase.assertEqual(Realm.schemaVersion('another.realm'), 2);
|
||||
|
||||
var encryptionKey = new Int8Array(64);
|
||||
realm = new Realm({schema: [], schemaVersion: 3, path: 'encrypted.realm', encryptionKey: encryptionKey});
|
||||
TestCase.assertEqual(realm.schemaVersion, 3);
|
||||
TestCase.assertEqual(Realm.schemaVersion('encrypted.realm', encryptionKey), 3);
|
||||
|
||||
TestCase.assertThrows(function() {
|
||||
Realm.schemaVersion('encrypted.realm', encryptionKey, 'extra');
|
||||
});
|
||||
TestCase.assertThrows(function() {
|
||||
Realm.schemaVersion('encrypted.realm', 'asdf');
|
||||
});
|
||||
},
|
||||
|
||||
testRealmWrite: function() {
|
||||
|
@ -35,10 +35,17 @@ class Worker {
|
||||
this._process.send(message);
|
||||
}
|
||||
}
|
||||
terminate() {
|
||||
terminate(cb) {
|
||||
if (!cb) {
|
||||
cb = function() { };
|
||||
}
|
||||
|
||||
if (this._process) {
|
||||
this._process.once('close', cb);
|
||||
this._process.kill();
|
||||
delete this._process;
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,13 +58,13 @@ for (const suiteName in tests) {
|
||||
try {
|
||||
let result = RealmTests.runTest(suiteName, testName);
|
||||
if (result instanceof Promise) {
|
||||
result.then(done, fail);
|
||||
result.then(done, done.fail.bind(done));
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
fail(e);
|
||||
done.fail(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user