Merge branch '2.0.x' of github.com:realm/realm-js into 2.0.x

This commit is contained in:
Kenneth Geisshirt 2017-09-08 16:10:52 +02:00
commit ad896aefee
23 changed files with 401 additions and 321 deletions

View File

@ -1,7 +1,7 @@
X.Y.Z Release notes
2.0.0 Release notes (2017-9-8)
=============================================================
### Breaking changes
* None
* Updating core, sync, object store.
### Enhancements
* Improve performance of the RPC worker for chrome debugging.

View File

@ -37,9 +37,6 @@
"type": "static_library",
"include_dirs": [
"src/object-store/src",
"src/object-store/src/impl",
"src/object-store/src/impl/apple",
"src/object-store/src/parser",
"src/object-store/external/pegtl"
],
"defines": [ "REALM_PLATFORM_NODE=1" ],
@ -49,6 +46,7 @@
"src/object-store/src/index_set.cpp",
"src/object-store/src/list.cpp",
"src/object-store/src/object.cpp",
"src/object-store/src/placeholder.cpp",
"src/object-store/src/object_schema.cpp",
"src/object-store/src/object_store.cpp",
"src/object-store/src/results.cpp",
@ -59,6 +57,7 @@
"src/object-store/src/impl/collection_notifier.cpp",
"src/object-store/src/impl/list_notifier.cpp",
"src/object-store/src/impl/object_notifier.cpp",
"src/object-store/src/impl/primitive_list_notifier.cpp",
"src/object-store/src/impl/realm_coordinator.cpp",
"src/object-store/src/impl/results_notifier.cpp",
"src/object-store/src/impl/transact_log_handler.cpp",
@ -66,6 +65,7 @@
"src/object-store/src/parser/parser.cpp",
"src/object-store/src/parser/query_builder.cpp",
"src/object-store/src/util/format.cpp",
"src/object-store/src/util/uuid.cpp",
],
"conditions": [
["OS=='win'", {

View File

@ -1,5 +1,5 @@
PACKAGE_NAME=realm-js
VERSION=2.0.0-rc5
REALM_CORE_VERSION=3.0.0-rc3
REALM_SYNC_VERSION=2.0.0-rc12
REALM_OBJECT_SERVER_VERSION=2.0.0-rc2
VERSION=2.0.0-rc6
REALM_CORE_VERSION=3.1.0
REALM_SYNC_VERSION=2.0.0-rc18
REALM_OBJECT_SERVER_VERSION=2.0.0-alpha.22

View File

@ -168,7 +168,7 @@ class User {
/**
* Create an admin user for the given authentication server with an existing token
* @param {string} adminToken - existing admin token
* @param {string} [server] - authentication server
* @param {string} server - authentication server
* @return {User} - admin user populated with the given token and server
*/
static adminUser(adminToken, server) {}

View File

@ -62,6 +62,10 @@ function print_error() {
}
function refreshAccessToken(user, localRealmPath, realmUrl) {
if (!user.server) {
throw new Error("Server for user must be specified");
}
let parsedRealmUrl = url_parse(realmUrl);
const url = auth_url(user.server);
const options = {
@ -75,8 +79,6 @@ function refreshAccessToken(user, localRealmPath, realmUrl) {
headers: postHeaders
};
performFetch(url, options)
// in case something lower in the HTTP stack breaks, try again in 10 seconds
.catch(() => setTimeout(() => refreshAccessToken(user, localRealmPath, realmUrl), 10 * 1000))
.then((response) => response.json().then((json) => { return { response, json }; }))
.then((responseAndJson) => {
const response = responseAndJson.response;
@ -111,7 +113,12 @@ function refreshAccessToken(user, localRealmPath, realmUrl) {
print_error(`Unhandled session token refresh error: could not look up session at path ${localRealmPath}`);
}
}
});
})
.catch((e) => {
print_error(e);
// in case something lower in the HTTP stack breaks, try again in 10 seconds
setTimeout(() => refreshAccessToken(user, localRealmPath, realmUrl), 10 * 1000);
})
}
function _authenticate(userConstructor, server, json, callback) {
@ -154,12 +161,8 @@ const staticMethods = {
},
adminUser(token, server) {
checkTypes(arguments, ['string']);
const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
return this.createUser(server || '', uuid, token, true);
checkTypes(arguments, ['string', 'string']);
return this._adminUser(server, token);
},
register(server, username, password, callback) {
@ -253,7 +256,6 @@ const instanceMethods = {
throw new AuthError(body);
});
} else {
return response.json();
}
});

View File

@ -1,11 +1,7 @@
{
"name": "realm",
"description": "Realm is a mobile database: an alternative to SQLite and key-value stores",
<<<<<<< HEAD
"version": "2.0.0-rc5",
=======
"version": "1.11.1",
>>>>>>> 38bceddfb19fd9f8ac5cc62ddb8bfa626270aa5c
"version": "2.0.0-rc6",
"license": "Apache-2.0",
"homepage": "https://realm.io",
"keywords": [

View File

@ -34,6 +34,7 @@ LOCAL_SRC_FILES += src/object-store/src/impl/collection_change_builder.cpp
LOCAL_SRC_FILES += src/object-store/src/impl/collection_notifier.cpp
LOCAL_SRC_FILES += src/object-store/src/impl/list_notifier.cpp
LOCAL_SRC_FILES += src/object-store/src/impl/object_notifier.cpp
LOCAL_SRC_FILES += src/object-store/src/impl/primitive_list_notifier.cpp
LOCAL_SRC_FILES += src/object-store/src/impl/realm_coordinator.cpp
LOCAL_SRC_FILES += src/object-store/src/impl/results_notifier.cpp
LOCAL_SRC_FILES += src/object-store/src/impl/transact_log_handler.cpp

View File

@ -14,6 +14,7 @@ if [ -f object-server-for-testing/node_modules/realm-object-server-developer/pac
fi
object_server_bundle="realm-object-server-bundled_node_darwin-developer-$REALM_OBJECT_SERVER_VERSION.tar.gz"
echo "Downloading https://static.realm.io/downloads/object-server/$object_server_bundle"
curl -f -L "https://static.realm.io/downloads/object-server/$object_server_bundle" -o "$object_server_bundle"
rm -rf object-server-for-testing
mkdir object-server-for-testing

View File

@ -174,11 +174,20 @@ if (!fs.existsSync(realmDir)) {
pipeline = pipeline.then(() => decompress(downloadedArchive, targetFolder, decompressOptions));
if (extractedFolder) {
pipeline = pipeline.then(() => fs.renameSync(path.resolve(vendorDir, extractedFolder), realmDir));
pipeline = pipeline.then(() => {
fs.renameSync(path.resolve(vendorDir, extractedFolder), realmDir);
const libDir = path.resolve(realmDir, 'lib')
if (fs.existsSync(libDir)) {
// Remove all shared libraries as we want to just use the static ones
fs.readdirSync(libDir)
.filter(name => /\.so$/.test(name))
.forEach(name => fs.unlinkSync(path.resolve(libDir, name)));
}
});
}
pipeline.catch(error => {
console.log('Downloading Realm binaries failed with', error);
process.exit(-1);
});
}
}

View File

@ -40,6 +40,9 @@
02F59EC51C88F17D007F774C /* shared_realm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02F59EBD1C88F17D007F774C /* shared_realm.cpp */; };
02F59EE21C88F2BB007F774C /* realm_coordinator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02F59EDB1C88F2BA007F774C /* realm_coordinator.cpp */; };
02F59EE31C88F2BB007F774C /* transact_log_handler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02F59EDD1C88F2BB007F774C /* transact_log_handler.cpp */; };
3FCE2A8B1F58BDEF00D4855B /* primitive_list_notifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FCE2A891F58BDE500D4855B /* primitive_list_notifier.cpp */; };
3FCE2A931F58BE0300D4855B /* uuid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FCE2A911F58BDFF00D4855B /* uuid.cpp */; };
3FCE2A971F58BE2200D4855B /* sync_permission.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FCE2A951F58BE1D00D4855B /* sync_permission.cpp */; };
502B07E41E2CD201007A84ED /* object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 502B07E31E2CD1FA007A84ED /* object.cpp */; };
504CF85E1EBCAE3600A9A4B6 /* network_reachability_observer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 504CF8541EBCAE3600A9A4B6 /* network_reachability_observer.cpp */; };
504CF85F1EBCAE3600A9A4B6 /* system_configuration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 504CF8561EBCAE3600A9A4B6 /* system_configuration.cpp */; };
@ -177,6 +180,19 @@
02F59EDC1C88F2BB007F774C /* realm_coordinator.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = realm_coordinator.hpp; sourceTree = "<group>"; };
02F59EDD1C88F2BB007F774C /* transact_log_handler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = transact_log_handler.cpp; sourceTree = "<group>"; };
02F59EDE1C88F2BB007F774C /* transact_log_handler.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = transact_log_handler.hpp; sourceTree = "<group>"; };
3FCE2A871F58BDE500D4855B /* object_accessor_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = object_accessor_impl.hpp; sourceTree = "<group>"; };
3FCE2A881F58BDE500D4855B /* primitive_list_notifier.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = primitive_list_notifier.hpp; sourceTree = "<group>"; };
3FCE2A891F58BDE500D4855B /* primitive_list_notifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = primitive_list_notifier.cpp; sourceTree = "<group>"; };
3FCE2A8C1F58BDFF00D4855B /* aligned_union.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = aligned_union.hpp; sourceTree = "<group>"; };
3FCE2A8D1F58BDFF00D4855B /* any.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = any.hpp; sourceTree = "<group>"; };
3FCE2A8E1F58BDFF00D4855B /* tagged_bool.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = tagged_bool.hpp; sourceTree = "<group>"; };
3FCE2A8F1F58BDFF00D4855B /* time.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = time.hpp; sourceTree = "<group>"; };
3FCE2A901F58BDFF00D4855B /* uuid.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = uuid.hpp; sourceTree = "<group>"; };
3FCE2A911F58BDFF00D4855B /* uuid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uuid.cpp; sourceTree = "<group>"; };
3FCE2A941F58BE1D00D4855B /* sync_permission.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = sync_permission.hpp; path = src/sync/sync_permission.hpp; sourceTree = "<group>"; };
3FCE2A951F58BE1D00D4855B /* sync_permission.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sync_permission.cpp; path = src/sync/sync_permission.cpp; sourceTree = "<group>"; };
3FCE2A981F58BE3600D4855B /* descriptor_ordering.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = descriptor_ordering.hpp; path = "object-store/src/descriptor_ordering.hpp"; sourceTree = SOURCE_ROOT; };
3FCE2A991F58BE3600D4855B /* feature_checks.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = feature_checks.hpp; path = "object-store/src/feature_checks.hpp"; sourceTree = SOURCE_ROOT; };
502B07E31E2CD1FA007A84ED /* object.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = object.cpp; path = src/object.cpp; sourceTree = "<group>"; };
502B07E51E2CD20D007A84ED /* object.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = object.hpp; path = src/object.hpp; sourceTree = "<group>"; };
504CF8541EBCAE3600A9A4B6 /* network_reachability_observer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = network_reachability_observer.cpp; sourceTree = "<group>"; };
@ -280,9 +296,9 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5D25F5A11D6284FD00EBBB30 /* libz.tbd in Frameworks */,
027A23131CD3E379000543AE /* libRealmJS.a in Frameworks */,
02D8D1F71B601984006DB49D /* JavaScriptCore.framework in Frameworks */,
027A23131CD3E379000543AE /* libRealmJS.a in Frameworks */,
5D25F5A11D6284FD00EBBB30 /* libz.tbd in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -301,13 +317,19 @@
children = (
02022A6C1DA47EC8000F0C4F /* android */,
02022A6E1DA47EC8000F0C4F /* apple */,
02022A751DA47EC8000F0C4F /* generic */,
02022A771DA47EC8000F0C4F /* uv */,
3FCE2A8C1F58BDFF00D4855B /* aligned_union.hpp */,
3FCE2A8D1F58BDFF00D4855B /* any.hpp */,
02022A701DA47EC8000F0C4F /* atomic_shared_ptr.hpp */,
02022A711DA47EC8000F0C4F /* compiler.hpp */,
02022A721DA47EC8000F0C4F /* event_loop_signal.hpp */,
02022A731DA47EC8000F0C4F /* format.cpp */,
02022A741DA47EC8000F0C4F /* format.hpp */,
02022A751DA47EC8000F0C4F /* generic */,
02022A771DA47EC8000F0C4F /* uv */,
3FCE2A8E1F58BDFF00D4855B /* tagged_bool.hpp */,
3FCE2A8F1F58BDFF00D4855B /* time.hpp */,
3FCE2A911F58BDFF00D4855B /* uuid.cpp */,
3FCE2A901F58BDFF00D4855B /* uuid.hpp */,
);
name = util;
path = src/util;
@ -348,30 +370,30 @@
0270BC3D1B7CFBFD00010E03 /* RealmJS */ = {
isa = PBXGroup;
children = (
F6BCCFDF1C83809A00FE31AE /* lib */,
02879D8B1DC29D5600777A5D /* package.json */,
F62A35131C18E6E2004A917D /* iOS */,
F6874A441CAD2ACD00EEEE36 /* JSC */,
F6BCCFDF1C83809A00FE31AE /* lib */,
F62BF9001CAC72C40022BCDC /* Node */,
F62A35141C18E783004A917D /* Object Store */,
F6079B181CD3EB9000BD2401 /* concurrent_deque.hpp */,
850715AE1E32366B00E548DB /* event_loop_dispatcher.hpp */,
0290934A1CEFA9170009769E /* js_observable.hpp */,
F620F0521CAF0B600082977B /* js_class.hpp */,
F60102F71CBDA6D400EC01BA /* js_collection.hpp */,
029048041C0428DF00ABDED4 /* js_list.hpp */,
029048061C0428DF00ABDED4 /* js_realm_object.hpp */,
F620F0591CB7B4C80082977B /* js_object_accessor.hpp */,
0290934A1CEFA9170009769E /* js_observable.hpp */,
029048071C0428DF00ABDED4 /* js_realm.cpp */,
029048081C0428DF00ABDED4 /* js_realm.hpp */,
0250D9C01D7647E00012C20C /* js_sync.hpp */,
029048061C0428DF00ABDED4 /* js_realm_object.hpp */,
0290480A1C0428DF00ABDED4 /* js_results.hpp */,
0290480C1C0428DF00ABDED4 /* js_schema.hpp */,
F620F0521CAF0B600082977B /* js_class.hpp */,
0250D9C01D7647E00012C20C /* js_sync.hpp */,
F6874A3E1CACA5A900EEEE36 /* js_types.hpp */,
F6267BC91CADC30000AC36B1 /* js_util.hpp */,
F620F0591CB7B4C80082977B /* js_object_accessor.hpp */,
02879D8B1DC29D5600777A5D /* package.json */,
029048351C042A3C00ABDED4 /* platform.hpp */,
0290480F1C0428DF00ABDED4 /* rpc.cpp */,
029048101C0428DF00ABDED4 /* rpc.hpp */,
F6079B181CD3EB9000BD2401 /* concurrent_deque.hpp */,
);
name = RealmJS;
sourceTree = "<group>";
@ -380,19 +402,19 @@
isa = PBXGroup;
children = (
02B58CCF1AE99D8C009B348C /* Frameworks */,
F6C3FBB41BF680D000E6FFD4 /* Vendor */,
02B58CB21AE99CEC009B348C /* Products */,
0270BC3D1B7CFBFD00010E03 /* RealmJS */,
02B58CC01AE99CEC009B348C /* RealmJSTests */,
02B58CB21AE99CEC009B348C /* Products */,
F6C3FBB41BF680D000E6FFD4 /* Vendor */,
);
sourceTree = "<group>";
};
02B58CB21AE99CEC009B348C /* Products */ = {
isa = PBXGroup;
children = (
02B58CBC1AE99CEC009B348C /* RealmJSTests.xctest */,
F63FF2B11C1241E500B3B8E0 /* libRealmJS.a */,
F63FF2F01C16405C00B3B8E0 /* libGCDWebServers.a */,
F63FF2B11C1241E500B3B8E0 /* libRealmJS.a */,
02B58CBC1AE99CEC009B348C /* RealmJSTests.xctest */,
);
name = Products;
sourceTree = "<group>";
@ -400,12 +422,12 @@
02B58CC01AE99CEC009B348C /* RealmJSTests */ = {
isa = PBXGroup;
children = (
F61378781C18EAAC008BFC51 /* js */,
02D041F51CE11159000E4250 /* data */,
F61378781C18EAAC008BFC51 /* js */,
0270BC781B7D020100010E03 /* Info.plist */,
02409DC11BCF11D6005F3B3E /* RealmJSCoreTests.m */,
0270BC7A1B7D020100010E03 /* RealmJSTests.h */,
0270BC7B1B7D020100010E03 /* RealmJSTests.mm */,
02409DC11BCF11D6005F3B3E /* RealmJSCoreTests.m */,
F68A278A1BC2722A0063D40A /* RJSModuleLoader.h */,
F68A278B1BC2722A0063D40A /* RJSModuleLoader.m */,
);
@ -416,14 +438,14 @@
02B58CCF1AE99D8C009B348C /* Frameworks */ = {
isa = PBXGroup;
children = (
F620F0741CB9F60C0082977B /* CoreFoundation.framework */,
02A3C7A41BC4341500B1A7BE /* libc++.tbd */,
F63FF3301C16434400B3B8E0 /* libz.tbd */,
F63FF32E1C16433900B3B8E0 /* libxml2.tbd */,
F63FF32C1C16432E00B3B8E0 /* CFNetwork.framework */,
F620F0741CB9F60C0082977B /* CoreFoundation.framework */,
02B58CCD1AE99D4D009B348C /* JavaScriptCore.framework */,
02A3C7A41BC4341500B1A7BE /* libc++.tbd */,
F63FF32E1C16433900B3B8E0 /* libxml2.tbd */,
F63FF3301C16434400B3B8E0 /* libz.tbd */,
F63FF32A1C16432700B3B8E0 /* MobileCoreServices.framework */,
F63FF3281C16430C00B3B8E0 /* UIKit.framework */,
02B58CCD1AE99D4D009B348C /* JavaScriptCore.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -442,13 +464,15 @@
children = (
504CF8521EBCAE3600A9A4B6 /* impl */,
02E315CD1DB80DF200555337 /* sync_client.hpp */,
02E315C21DB80DDD00555337 /* sync_config.hpp */,
02E315CE1DB80DF200555337 /* sync_file.cpp */,
02E315CF1DB80DF200555337 /* sync_file.hpp */,
02E315D01DB80DF200555337 /* sync_metadata.cpp */,
02E315D11DB80DF200555337 /* sync_metadata.hpp */,
02E315C21DB80DDD00555337 /* sync_config.hpp */,
02E315C31DB80DDD00555337 /* sync_manager.cpp */,
02E315C41DB80DDD00555337 /* sync_manager.hpp */,
02E315D01DB80DF200555337 /* sync_metadata.cpp */,
02E315D11DB80DF200555337 /* sync_metadata.hpp */,
3FCE2A951F58BE1D00D4855B /* sync_permission.cpp */,
3FCE2A941F58BE1D00D4855B /* sync_permission.hpp */,
02E315C51DB80DDD00555337 /* sync_session.cpp */,
02E315C61DB80DDD00555337 /* sync_session.hpp */,
02E315C71DB80DDD00555337 /* sync_user.cpp */,
@ -486,8 +510,8 @@
F62A35131C18E6E2004A917D /* iOS */ = {
isa = PBXGroup;
children = (
029048381C042A8F00ABDED4 /* platform.mm */,
0270BC5A1B7CFC1300010E03 /* Info.plist */,
029048381C042A8F00ABDED4 /* platform.mm */,
);
name = iOS;
path = ios;
@ -496,16 +520,18 @@
F62A35141C18E783004A917D /* Object Store */ = {
isa = PBXGroup;
children = (
02E315CC1DB80DE000555337 /* sync */,
02022A6B1DA47EC8000F0C4F /* util */,
F63117EA1CEB0BFA00ECB2DE /* impl */,
F63117EC1CEB0C8100ECB2DE /* parser */,
022BF1001E7266C800F382F1 /* binding_callback_thread_observer.hpp */,
02E315CC1DB80DE000555337 /* sync */,
02022A6B1DA47EC8000F0C4F /* util */,
022BF0FF1E7266C800F382F1 /* binding_callback_thread_observer.cpp */,
022BF1001E7266C800F382F1 /* binding_callback_thread_observer.hpp */,
02F59EAE1C88F17D007F774C /* binding_context.hpp */,
02414B961CE6AADD00A8669F /* collection_notifications.cpp */,
02414B971CE6AADD00A8669F /* collection_notifications.hpp */,
3FCE2A981F58BE3600D4855B /* descriptor_ordering.hpp */,
5D02C7781E1C83650048C13E /* execution_context_id.hpp */,
3FCE2A991F58BE3600D4855B /* feature_checks.hpp */,
02F59EAF1C88F17D007F774C /* index_set.cpp */,
02F59EB01C88F17D007F774C /* index_set.hpp */,
02F59EB11C88F17D007F774C /* list.cpp */,
@ -535,19 +561,19 @@
F62BF9001CAC72C40022BCDC /* Node */ = {
isa = PBXGroup;
children = (
F6267BCA1CADC49200AC36B1 /* node_dummy.cpp */,
F60102CF1CBB814A00EC01BA /* node_init.hpp */,
F620F0571CB766DA0082977B /* node_init.cpp */,
F620F0551CB655A50082977B /* node_class.hpp */,
F6874A351CAC792D00EEEE36 /* node_types.hpp */,
F60103161CC4CD2F00EC01BA /* node_string.hpp */,
F601030A1CC4B64E00EC01BA /* node_context.hpp */,
F601030C1CC4B72B00EC01BA /* node_value.hpp */,
F601030E1CC4B7C900EC01BA /* node_object.hpp */,
F60103101CC4B86000EC01BA /* node_function.hpp */,
F6267BCA1CADC49200AC36B1 /* node_dummy.cpp */,
F60103121CC4CBF000EC01BA /* node_exception.hpp */,
F60103101CC4B86000EC01BA /* node_function.hpp */,
F620F0571CB766DA0082977B /* node_init.cpp */,
F60102CF1CBB814A00EC01BA /* node_init.hpp */,
F601030E1CC4B7C900EC01BA /* node_object.hpp */,
F60103071CC4B3DF00EC01BA /* node_protected.hpp */,
F60103151CC4CCFD00EC01BA /* node_return_value.hpp */,
F60103161CC4CD2F00EC01BA /* node_string.hpp */,
F6874A351CAC792D00EEEE36 /* node_types.hpp */,
F601030C1CC4B72B00EC01BA /* node_value.hpp */,
F67478481CC81F1300F9273C /* platform.cpp */,
);
name = Node;
@ -564,19 +590,22 @@
02414B9A1CE6AAEF00A8669F /* collection_change_builder.hpp */,
02414B9B1CE6AAEF00A8669F /* collection_notifier.cpp */,
02414B9C1CE6AAEF00A8669F /* collection_notifier.hpp */,
02F59EDA1C88F2BA007F774C /* external_commit_helper.hpp */,
02414B9D1CE6AAEF00A8669F /* list_notifier.cpp */,
02414B9E1CE6AAEF00A8669F /* list_notifier.hpp */,
3FCE2A871F58BDE500D4855B /* object_accessor_impl.hpp */,
8507156B1E2CFC0100E548DB /* object_notifier.cpp */,
8507156C1E2CFC0100E548DB /* object_notifier.hpp */,
02414B9F1CE6AAEF00A8669F /* results_notifier.cpp */,
02414BA01CE6AAEF00A8669F /* results_notifier.hpp */,
02F59EDA1C88F2BA007F774C /* external_commit_helper.hpp */,
3FCE2A891F58BDE500D4855B /* primitive_list_notifier.cpp */,
3FCE2A881F58BDE500D4855B /* primitive_list_notifier.hpp */,
02F59EDB1C88F2BA007F774C /* realm_coordinator.cpp */,
02F59EDC1C88F2BB007F774C /* realm_coordinator.hpp */,
02414B9F1CE6AAEF00A8669F /* results_notifier.cpp */,
02414BA01CE6AAEF00A8669F /* results_notifier.hpp */,
02F59EDD1C88F2BB007F774C /* transact_log_handler.cpp */,
02F59EDE1C88F2BB007F774C /* transact_log_handler.hpp */,
02022A481DA474A7000F0C4F /* weak_realm_notifier.hpp */,
02022A4A1DA475A9000F0C4F /* weak_realm_notifier.cpp */,
02022A481DA474A7000F0C4F /* weak_realm_notifier.hpp */,
);
name = impl;
path = src/impl;
@ -585,10 +614,10 @@
F63117EB1CEB0C1B00ECB2DE /* apple */ = {
isa = PBXGroup;
children = (
02E315DE1DB8233E00555337 /* keychain_helper.cpp */,
02E315DF1DB8233E00555337 /* keychain_helper.hpp */,
02022A411DA47489000F0C4F /* external_commit_helper.cpp */,
02022A421DA47489000F0C4F /* external_commit_helper.hpp */,
02E315DE1DB8233E00555337 /* keychain_helper.cpp */,
02E315DF1DB8233E00555337 /* keychain_helper.hpp */,
);
path = apple;
sourceTree = "<group>";
@ -686,20 +715,20 @@
F6874A441CAD2ACD00EEEE36 /* JSC */ = {
isa = PBXGroup;
children = (
F620F0531CAF2EF70082977B /* jsc_class.hpp */,
F60103091CC4B5E800EC01BA /* jsc_context.hpp */,
F60103111CC4BA6500EC01BA /* jsc_exception.hpp */,
F601030F1CC4B80800EC01BA /* jsc_function.hpp */,
029048011C0428DF00ABDED4 /* jsc_init.cpp */,
029048021C0428DF00ABDED4 /* jsc_init.h */,
F60102D11CBB865A00EC01BA /* jsc_init.hpp */,
029048011C0428DF00ABDED4 /* jsc_init.cpp */,
F620F0531CAF2EF70082977B /* jsc_class.hpp */,
025678951CAB392000FB8501 /* jsc_types.hpp */,
F60103131CC4CC4500EC01BA /* jsc_string.hpp */,
F60103091CC4B5E800EC01BA /* jsc_context.hpp */,
F601030B1CC4B6C900EC01BA /* jsc_value.hpp */,
5D1BF0561EF1DB4800B7DC87 /* jsc_value.cpp */,
F601030D1CC4B76F00EC01BA /* jsc_object.hpp */,
F601030F1CC4B80800EC01BA /* jsc_function.hpp */,
F60103111CC4BA6500EC01BA /* jsc_exception.hpp */,
F60103081CC4B4F900EC01BA /* jsc_protected.hpp */,
F60103141CC4CC8C00EC01BA /* jsc_return_value.hpp */,
F60103131CC4CC4500EC01BA /* jsc_string.hpp */,
025678951CAB392000FB8501 /* jsc_types.hpp */,
5D1BF0561EF1DB4800B7DC87 /* jsc_value.cpp */,
F601030B1CC4B6C900EC01BA /* jsc_value.hpp */,
);
name = JSC;
path = jsc;
@ -709,8 +738,8 @@
isa = PBXGroup;
children = (
F63FF2FB1C1642BB00B3B8E0 /* GCDWebServer */,
F6BB7DF01BF681BC00D0A69E /* base64.hpp */,
F6BB7DEF1BF681BC00D0A69E /* base64.cpp */,
F6BB7DF01BF681BC00D0A69E /* base64.hpp */,
F6C3FBBC1BF680EC00E6FFD4 /* json.hpp */,
);
name = Vendor;
@ -816,9 +845,9 @@
buildActionMask = 2147483647;
files = (
02D041F71CE11159000E4250 /* dates-v3.realm in Resources */,
F6BCCFE21C8380A400FE31AE /* lib in Resources */,
02414B881CE68CA200A8669F /* dates-v5.realm in Resources */,
F61378791C18EAC5008BFC51 /* js in Resources */,
F6BCCFE21C8380A400FE31AE /* lib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -861,9 +890,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F68A278C1BC2722A0063D40A /* RJSModuleLoader.m in Sources */,
0270BC821B7D020100010E03 /* RealmJSTests.mm in Sources */,
02409DC21BCF11D6005F3B3E /* RealmJSCoreTests.m in Sources */,
0270BC821B7D020100010E03 /* RealmJSTests.mm in Sources */,
F68A278C1BC2722A0063D40A /* RJSModuleLoader.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -871,46 +900,49 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
02E315C91DB80DDD00555337 /* sync_manager.cpp in Sources */,
02022A671DA47BD7000F0C4F /* parser.cpp in Sources */,
02022A681DA47BD7000F0C4F /* query_builder.cpp in Sources */,
02E315E01DB8233E00555337 /* keychain_helper.cpp in Sources */,
02022A581DA476CD000F0C4F /* external_commit_helper.cpp in Sources */,
02022A5A1DA476CD000F0C4F /* weak_realm_notifier.cpp in Sources */,
02022A5B1DA476CD000F0C4F /* placeholder.cpp in Sources */,
504CF8611EBCAE3600A9A4B6 /* sync_metadata.cpp in Sources */,
502B07E41E2CD201007A84ED /* object.cpp in Sources */,
02414BA51CE6ABCF00A8669F /* collection_change_builder.cpp in Sources */,
02414BA61CE6ABCF00A8669F /* collection_notifier.cpp in Sources */,
504CF85F1EBCAE3600A9A4B6 /* system_configuration.cpp in Sources */,
02414BA71CE6ABCF00A8669F /* list_notifier.cpp in Sources */,
504CF8601EBCAE3600A9A4B6 /* sync_file.cpp in Sources */,
02414BA81CE6ABCF00A8669F /* results_notifier.cpp in Sources */,
02414BA91CE6ABCF00A8669F /* collection_notifications.cpp in Sources */,
02F59EE31C88F2BB007F774C /* transact_log_handler.cpp in Sources */,
F63FF2E81C159C4B00B3B8E0 /* platform.mm in Sources */,
50C671001E1D2D31003CB63C /* thread_safe_reference.cpp in Sources */,
8507156E1E2CFCD000E548DB /* object_notifier.cpp in Sources */,
02E315CA1DB80DDD00555337 /* sync_session.cpp in Sources */,
02F59EC31C88F17D007F774C /* results.cpp in Sources */,
F63FF2E21C15921A00B3B8E0 /* base64.cpp in Sources */,
F63FF2C61C12469E00B3B8E0 /* jsc_init.cpp in Sources */,
02F59EC01C88F17D007F774C /* list.cpp in Sources */,
022BF1021E7266DF00F382F1 /* binding_callback_thread_observer.cpp in Sources */,
02414BA51CE6ABCF00A8669F /* collection_change_builder.cpp in Sources */,
02414BA91CE6ABCF00A8669F /* collection_notifications.cpp in Sources */,
02414BA61CE6ABCF00A8669F /* collection_notifier.cpp in Sources */,
02022A581DA476CD000F0C4F /* external_commit_helper.cpp in Sources */,
02022A7C1DA47EC8000F0C4F /* format.cpp in Sources */,
02F59EBF1C88F17D007F774C /* index_set.cpp in Sources */,
F63FF2C91C12469E00B3B8E0 /* js_realm.cpp in Sources */,
02F59EC51C88F17D007F774C /* shared_realm.cpp in Sources */,
504CF85E1EBCAE3600A9A4B6 /* network_reachability_observer.cpp in Sources */,
02F59EE21C88F2BB007F774C /* realm_coordinator.cpp in Sources */,
02F59EC41C88F17D007F774C /* schema.cpp in Sources */,
F63FF2CD1C12469E00B3B8E0 /* rpc.cpp in Sources */,
02E315D21DB80DF200555337 /* sync_file.cpp in Sources */,
022BF1021E7266DF00F382F1 /* binding_callback_thread_observer.cpp in Sources */,
F63FF2C61C12469E00B3B8E0 /* jsc_init.cpp in Sources */,
5D1BF0571EF1DB4800B7DC87 /* jsc_value.cpp in Sources */,
02F59EC21C88F17D007F774C /* object_store.cpp in Sources */,
02022A7C1DA47EC8000F0C4F /* format.cpp in Sources */,
02E315CB1DB80DDD00555337 /* sync_user.cpp in Sources */,
02E315D31DB80DF200555337 /* sync_metadata.cpp in Sources */,
02E315E01DB8233E00555337 /* keychain_helper.cpp in Sources */,
02F59EC01C88F17D007F774C /* list.cpp in Sources */,
02414BA71CE6ABCF00A8669F /* list_notifier.cpp in Sources */,
504CF85E1EBCAE3600A9A4B6 /* network_reachability_observer.cpp in Sources */,
502B07E41E2CD201007A84ED /* object.cpp in Sources */,
8507156E1E2CFCD000E548DB /* object_notifier.cpp in Sources */,
02F59EC11C88F17D007F774C /* object_schema.cpp in Sources */,
02F59EC21C88F17D007F774C /* object_store.cpp in Sources */,
02022A671DA47BD7000F0C4F /* parser.cpp in Sources */,
02022A5B1DA476CD000F0C4F /* placeholder.cpp in Sources */,
F63FF2E81C159C4B00B3B8E0 /* platform.mm in Sources */,
3FCE2A8B1F58BDEF00D4855B /* primitive_list_notifier.cpp in Sources */,
02022A681DA47BD7000F0C4F /* query_builder.cpp in Sources */,
02F59EE21C88F2BB007F774C /* realm_coordinator.cpp in Sources */,
02F59EC31C88F17D007F774C /* results.cpp in Sources */,
02414BA81CE6ABCF00A8669F /* results_notifier.cpp in Sources */,
F63FF2CD1C12469E00B3B8E0 /* rpc.cpp in Sources */,
02F59EC41C88F17D007F774C /* schema.cpp in Sources */,
02F59EC51C88F17D007F774C /* shared_realm.cpp in Sources */,
504CF8601EBCAE3600A9A4B6 /* sync_file.cpp in Sources */,
02E315D21DB80DF200555337 /* sync_file.cpp in Sources */,
02E315C91DB80DDD00555337 /* sync_manager.cpp in Sources */,
504CF8611EBCAE3600A9A4B6 /* sync_metadata.cpp in Sources */,
02E315D31DB80DF200555337 /* sync_metadata.cpp in Sources */,
3FCE2A971F58BE2200D4855B /* sync_permission.cpp in Sources */,
02E315CA1DB80DDD00555337 /* sync_session.cpp in Sources */,
02E315CB1DB80DDD00555337 /* sync_user.cpp in Sources */,
504CF85F1EBCAE3600A9A4B6 /* system_configuration.cpp in Sources */,
50C671001E1D2D31003CB63C /* thread_safe_reference.cpp in Sources */,
02F59EE31C88F2BB007F774C /* transact_log_handler.cpp in Sources */,
3FCE2A931F58BE0300D4855B /* uuid.cpp in Sources */,
02022A5A1DA476CD000F0C4F /* weak_realm_notifier.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -918,19 +950,19 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F63FF31E1C1642BB00B3B8E0 /* GCDWebServerRequest.m in Sources */,
F63FF3231C1642BB00B3B8E0 /* GCDWebServerURLEncodedFormRequest.m in Sources */,
F63FF31B1C1642BB00B3B8E0 /* GCDWebServer.m in Sources */,
F63FF31C1C1642BB00B3B8E0 /* GCDWebServerConnection.m in Sources */,
F63FF3201C1642BB00B3B8E0 /* GCDWebServerDataRequest.m in Sources */,
F63FF3221C1642BB00B3B8E0 /* GCDWebServerMultiPartFormRequest.m in Sources */,
F63FF3211C1642BB00B3B8E0 /* GCDWebServerFileRequest.m in Sources */,
F63FF31F1C1642BB00B3B8E0 /* GCDWebServerResponse.m in Sources */,
F63FF3261C1642BB00B3B8E0 /* GCDWebServerFileResponse.m in Sources */,
F63FF3271C1642BB00B3B8E0 /* GCDWebServerStreamedResponse.m in Sources */,
F63FF3241C1642BB00B3B8E0 /* GCDWebServerDataResponse.m in Sources */,
F63FF31B1C1642BB00B3B8E0 /* GCDWebServer.m in Sources */,
F63FF31D1C1642BB00B3B8E0 /* GCDWebServerFunctions.m in Sources */,
F63FF3251C1642BB00B3B8E0 /* GCDWebServerErrorResponse.m in Sources */,
F63FF3211C1642BB00B3B8E0 /* GCDWebServerFileRequest.m in Sources */,
F63FF3261C1642BB00B3B8E0 /* GCDWebServerFileResponse.m in Sources */,
F63FF31D1C1642BB00B3B8E0 /* GCDWebServerFunctions.m in Sources */,
F63FF3221C1642BB00B3B8E0 /* GCDWebServerMultiPartFormRequest.m in Sources */,
F63FF31E1C1642BB00B3B8E0 /* GCDWebServerRequest.m in Sources */,
F63FF31F1C1642BB00B3B8E0 /* GCDWebServerResponse.m in Sources */,
F63FF3271C1642BB00B3B8E0 /* GCDWebServerStreamedResponse.m in Sources */,
F63FF3231C1642BB00B3B8E0 /* GCDWebServerURLEncodedFormRequest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -22,8 +22,6 @@
#include "js_realm_object.hpp"
#include "js_schema.hpp"
#include "util/format.hpp"
namespace realm {
class List;
class Object;
@ -65,8 +63,9 @@ public:
ValueType value = Object::get_property(m_ctx, object, prop_name);
const auto& prop = m_object_schema.persisted_properties[prop_index];
if (!Value::is_valid_for_property(m_ctx, value, prop)) {
throw TypeErrorException(util::format("%1.%2", m_object_schema.name, prop.name),
js_type_name_for_property_type(prop.type));
throw TypeErrorException(m_object_schema.name, prop.name,
js_type_name_for_property_type(prop.type),
print(value));
}
return value;
}
@ -117,11 +116,19 @@ public:
}
}
bool is_same_list(realm::List const& list, ValueType const& value) const noexcept {
auto object = Value::validated_to_object(m_ctx, value);
if (js::Object<JSEngine>::template is_instance<ListClass<JSEngine>>(m_ctx, object)) {
return list == *get_internal<JSEngine, ListClass<JSEngine>>(object);
}
return false;
}
bool allow_missing(ValueType const&) const noexcept { return false; }
void will_change(realm::Object&, realm::Property const&) { }
void did_change() { }
std::string print(ValueType const&) { return "not implemented"; }
std::string print(ValueType const& v) { return Value::to_string(m_ctx, v); }
private:
ContextType m_ctx;

View File

@ -383,7 +383,7 @@ void RealmClass<T>::constructor(ContextType ctx, ObjectType this_object, size_t
static const String read_only_string = "readOnly";
ValueType read_only_value = Object::get_property(ctx, object, read_only_string);
if (!Value::is_undefined(ctx, read_only_value) && Value::validated_to_boolean(ctx, read_only_value, "readOnly")) {
config.schema_mode = SchemaMode::ReadOnly;
config.schema_mode = SchemaMode::Immutable;
}
static const String schema_string = "schema";
@ -596,7 +596,7 @@ void RealmClass<T>::get_schema(ContextType ctx, ObjectType object, ReturnValue &
template<typename T>
void RealmClass<T>::get_read_only(ContextType ctx, ObjectType object, ReturnValue &return_value) {
return_value.set(get_internal<T, RealmClass<T>>(object)->get()->config().read_only());
return_value.set(get_internal<T, RealmClass<T>>(object)->get()->config().immutable());
}
template<typename T>

View File

@ -49,7 +49,7 @@ struct RealmObjectClass : ClassDefinition<T, realm::Object> {
static void get_property(ContextType, ObjectType, const String &, ReturnValue &);
static bool set_property(ContextType, ObjectType, const String &, ValueType);
static std::vector<String> get_property_names(ContextType, ObjectType);
static void is_valid(ContextType, FunctionType, ObjectType, size_t, const ValueType [], ReturnValue &);
static void get_object_schema(ContextType, FunctionType, ObjectType, size_t, const ValueType [], ReturnValue &);
static void linking_objects(ContextType, FunctionType, ObjectType, size_t, const ValueType [], ReturnValue &);
@ -73,13 +73,13 @@ template<typename T>
void RealmObjectClass<T>::is_valid(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
return_value.set(get_internal<T, RealmObjectClass<T>>(this_object)->is_valid());
}
template<typename T>
void RealmObjectClass<T>::get_object_schema(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
auto object = get_internal<T, RealmObjectClass<T>>(this_object);
return_value.set(Schema<T>::object_for_object_schema(ctx, object->get_object_schema()));
}
template<typename T>
typename T::Object RealmObjectClass<T>::create_instance(ContextType ctx, realm::Object realm_object) {
static String prototype_string = "prototype";
@ -100,7 +100,7 @@ typename T::Object RealmObjectClass<T>::create_instance(ContextType ctx, realm::
if (result != object && !Value::is_null(ctx, result) && !Value::is_undefined(ctx, result)) {
throw std::runtime_error("Realm object constructor must not return another value");
}
return object;
}
@ -127,12 +127,13 @@ bool RealmObjectClass<T>::set_property(ContextType ctx, ObjectType object, const
return false;
}
NativeAccessor<T> accessor(ctx, realm_object->realm(), realm_object->get_object_schema());
if (!Value::is_valid_for_property(ctx, value, *prop)) {
throw TypeErrorException(util::format("%1.%2", realm_object->get_object_schema().name, property_name),
js_type_name_for_property_type(prop->type));
throw TypeErrorException(realm_object->get_object_schema().name, property_name,
js_type_name_for_property_type(prop->type),
accessor.print(value));
}
NativeAccessor<T> accessor(ctx, realm_object->realm(), realm_object->get_object_schema());
realm_object->set_property_value(accessor, property_name, value, true);
return true;
}
@ -162,29 +163,29 @@ std::vector<String<T>> RealmObjectClass<T>::get_property_names(ContextType ctx,
template<typename T>
void realm::js::RealmObjectClass<T>::linking_objects(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 2);
std::string object_type = Value::validated_to_string(ctx, arguments[0], "objectType");
std::string property_name = Value::validated_to_string(ctx, arguments[1], "property");
auto object = get_internal<T, RealmObjectClass<T>>(this_object);
auto target_object_schema = object->realm()->schema().find(object_type);
if (target_object_schema == object->realm()->schema().end()) {
throw std::logic_error(util::format("Could not find schema for type '%1'", object_type));
}
auto link_property = target_object_schema->property_for_name(property_name);
if (!link_property) {
throw std::logic_error(util::format("Type '%1' does not contain property '%2'", object_type, property_name));
}
if (link_property->object_type != object->get_object_schema().name) {
throw std::logic_error(util::format("'%1.%2' is not a relationship to '%3'", object_type, property_name, object->get_object_schema().name));
}
realm::TableRef table = ObjectStore::table_for_object_type(object->realm()->read_group(), target_object_schema->name);
auto row = object->row();
auto tv = row.get_table()->get_backlink_view(row.get_index(), table.get(), link_property->table_column);
return_value.set(ResultsClass<T>::create_instance(ctx, realm::Results(object->realm(), std::move(tv))));
}

View File

@ -53,7 +53,7 @@ struct Schema {
template<typename T>
typename T::Object Schema<T>::dict_for_property_array(ContextType ctx, const ObjectSchema &object_schema, ObjectType array) {
size_t count = object_schema.persisted_properties.size();
if (count != Object::validated_get_length(ctx, array)) {
throw std::runtime_error("Array must contain values for all object properties");
}
@ -76,56 +76,59 @@ Property Schema<T>::parse_property(ContextType ctx, ValueType attributes, std::s
static const String object_type_string = "objectType";
static const String optional_string = "optional";
static const String property_string = "property";
Property prop;
prop.name = property_name;
ObjectType property_object = {};
std::string type;
using realm::PropertyType;
PropertyType is_optional = PropertyType::Required;
if (Value::is_object(ctx, attributes)) {
property_object = Value::validated_to_object(ctx, attributes);
type = Object::validated_get_string(ctx, property_object, type_string);
ValueType optional_value = Object::get_property(ctx, property_object, optional_string);
if (!Value::is_undefined(ctx, optional_value)) {
prop.is_nullable = Value::validated_to_boolean(ctx, optional_value, "optional");
if (!Value::is_undefined(ctx, optional_value) && Value::validated_to_boolean(ctx, optional_value, "optional")) {
is_optional = PropertyType::Nullable;
}
}
else {
type = Value::validated_to_string(ctx, attributes);
}
if (type == "bool") {
prop.type = realm::PropertyType::Bool;
prop.type = PropertyType::Bool | is_optional;
}
else if (type == "int") {
prop.type = realm::PropertyType::Int;
prop.type = PropertyType::Int | is_optional;
}
else if (type == "float") {
prop.type = realm::PropertyType::Float;
prop.type = PropertyType::Float | is_optional;
}
else if (type == "double") {
prop.type = realm::PropertyType::Double;
prop.type = PropertyType::Double | is_optional;
}
else if (type == "string") {
prop.type = realm::PropertyType::String;
prop.type = PropertyType::String | is_optional;
}
else if (type == "date") {
prop.type = realm::PropertyType::Date;
prop.type = PropertyType::Date | is_optional;
}
else if (type == "data") {
prop.type = realm::PropertyType::Data;
prop.type = PropertyType::Data | is_optional;
}
else if (type == "list") {
if (!Value::is_valid(property_object)) {
throw std::runtime_error("List property must specify 'objectType'");
}
prop.type = realm::PropertyType::Array;
prop.type = PropertyType::Object | PropertyType::Array;
prop.object_type = Object::validated_get_string(ctx, property_object, object_type_string);
}
else if (type == "linkingObjects") {
prop.type = realm::PropertyType::LinkingObjects;
prop.type = PropertyType::LinkingObjects | PropertyType::Array;
if (!Value::is_valid(property_object)) {
throw std::runtime_error("Object property must specify 'objectType'");
@ -134,9 +137,8 @@ Property Schema<T>::parse_property(ContextType ctx, ValueType attributes, std::s
prop.link_origin_property_name = Object::validated_get_string(ctx, property_object, property_string);
}
else if (type == "object") {
prop.type = realm::PropertyType::Object;
prop.is_nullable = true;
prop.type = PropertyType::Object | PropertyType::Nullable;
if (!Value::is_valid(property_object)) {
throw std::runtime_error("Object property must specify 'objectType'");
}
@ -144,23 +146,22 @@ Property Schema<T>::parse_property(ContextType ctx, ValueType attributes, std::s
}
else {
// The type could be the name of another object type in the same schema.
prop.type = realm::PropertyType::Object;
prop.is_nullable = true;
prop.type = PropertyType::Object | PropertyType::Nullable;
prop.object_type = type;
}
if (Value::is_valid(property_object)) {
ValueType default_value = Object::get_property(ctx, property_object, default_string);
if (!Value::is_undefined(ctx, default_value)) {
object_defaults.emplace(prop.name, Protected<ValueType>(ctx, default_value));
}
ValueType indexed_value = Object::get_property(ctx, property_object, indexed_string);
if (!Value::is_undefined(ctx, indexed_value)) {
prop.is_indexed = Value::validated_to_boolean(ctx, indexed_value);
}
}
return prop;
}
@ -170,17 +171,17 @@ ObjectSchema Schema<T>::parse_object_schema(ContextType ctx, ObjectType object_s
static const String primary_string = "primaryKey";
static const String properties_string = "properties";
static const String schema_string = "schema";
FunctionType object_constructor = {};
if (Value::is_constructor(ctx, object_schema_object)) {
object_constructor = Value::to_constructor(ctx, object_schema_object);
object_schema_object = Object::validated_get_object(ctx, object_constructor, schema_string, "Realm object constructor must have a 'schema' property.");
}
ObjectDefaults object_defaults;
ObjectSchema object_schema;
object_schema.name = Object::validated_get_string(ctx, object_schema_object, name_string);
ObjectType properties_object = Object::validated_get_object(ctx, object_schema_object, properties_string, "ObjectSchema must have a 'properties' object.");
if (Value::is_array(ctx, properties_object)) {
uint32_t length = Object::validated_get_length(ctx, properties_object);
@ -194,7 +195,7 @@ ObjectSchema Schema<T>::parse_object_schema(ContextType ctx, ObjectType object_s
else {
object_schema.persisted_properties.emplace_back(std::move(property));
}
}
}
else {
@ -220,14 +221,14 @@ ObjectSchema Schema<T>::parse_object_schema(ContextType ctx, ObjectType object_s
}
property->is_primary = true;
}
// Store prototype so that objects of this type will have their prototype set to this prototype object.
if (Value::is_valid(object_constructor)) {
constructors.emplace(object_schema.name, Protected<FunctionType>(ctx, object_constructor));
}
defaults.emplace(object_schema.name, std::move(object_defaults));
return object_schema;
}
@ -289,7 +290,7 @@ typename T::Object Schema<T>::object_for_property(ContextType ctx, const Propert
Object::set_property(ctx, object, name_string, Value::from_string(ctx, property.name));
static const String type_string = "type";
const std::string type = property.type != realm::PropertyType::Array ? string_for_property_type(property.type) : "list";
const std::string type = is_array(property.type) ? "list" : string_for_property_type(property.type);
Object::set_property(ctx, object, type_string, Value::from_string(ctx, type));
static const String object_type_string = "objectType";
@ -308,7 +309,7 @@ typename T::Object Schema<T>::object_for_property(ContextType ctx, const Propert
}
static const String optional_string = "optional";
if (property.is_nullable) {
if (is_nullable(property.type)) {
Object::set_property(ctx, object, optional_string, Value::from_boolean(ctx, true));
}

View File

@ -71,9 +71,11 @@ public:
};
static void create_user(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
static void admin_user(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
MethodMap<T> const static_methods = {
{"createUser", wrap<create_user>}
{"createUser", wrap<create_user>},
{"_adminUser", wrap<admin_user>}
};
/*static void current_user(ContextType ctx, ObjectType object, ReturnValue &return_value);*/
@ -119,11 +121,14 @@ void UserClass<T>::is_admin(ContextType ctx, ObjectType object, ReturnValue &ret
template<typename T>
void UserClass<T>::create_user(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 3, 5);
SharedUser *user = new SharedUser(SyncManager::shared().get_user(
SyncUserIdentifier userIdentifier {
Value::validated_to_string(ctx, arguments[1], "identity"),
Value::validated_to_string(ctx, arguments[2], "refreshToken"),
(std::string)Value::validated_to_string(ctx, arguments[0], "authServerUrl"),
Value::validated_to_boolean(ctx, arguments[3], "isAdminToken") ? SyncUser::TokenType::Admin : SyncUser::TokenType::Normal));
Value::validated_to_string(ctx, arguments[0], "authServerUrl")
};
SharedUser *user = new SharedUser(SyncManager::shared().get_user(
userIdentifier,
Value::validated_to_string(ctx, arguments[2], "refreshToken")
));
if (argc == 5) {
(*user)->set_is_admin(Value::validated_to_boolean(ctx, arguments[4], "isAdmin"));
@ -131,6 +136,16 @@ void UserClass<T>::create_user(ContextType ctx, FunctionType, ObjectType this_ob
return_value.set(create_object<T, UserClass<T>>(ctx, user));
}
template<typename T>
void UserClass<T>::admin_user(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 2, 2);
SharedUser *user = new SharedUser(SyncManager::shared().get_admin_token_user(
Value::validated_to_string(ctx, arguments[0], "authServerUrl"),
Value::validated_to_string(ctx, arguments[1], "refreshToken")
));
return_value.set(create_object<T, UserClass<T>>(ctx, user));
}
template<typename T>
void UserClass<T>::all_users(ContextType ctx, ObjectType object, ReturnValue &return_value) {
auto users = Object::create_empty(ctx);
@ -432,7 +447,7 @@ void SyncClass<T>::populate_sync_config(ContextType ctx, ObjectType realm_constr
nullptr, util::none,
client_validate_ssl, ssl_trust_certificate_path});
config.schema_mode = SchemaMode::Additive;
config.path = realm::SyncManager::shared().path_for_realm(shared_user->identity(), raw_realm_url);
config.path = realm::SyncManager::shared().path_for_realm(*shared_user, raw_realm_url);
if (!config.encryption_key.empty()) {
config.sync_config->realm_encryption_key = std::array<char, 64>();

View File

@ -20,6 +20,7 @@
#include "execution_context_id.hpp"
#include "property.hpp"
#include "util/format.hpp"
#include <stdexcept>
#include <string>
@ -80,18 +81,16 @@ struct Context {
class TypeErrorException : public std::invalid_argument {
public:
std::string const& prefix() const { return m_prefix; }
std::string const& type() const { return m_type; }
TypeErrorException(StringData object_type, StringData property,
std::string const& type, std::string const& value)
: std::invalid_argument(util::format("%1.%2 must be of type '%3', got (%4)",
object_type, property, type, value))
{}
TypeErrorException(std::string prefix, std::string type) :
std::invalid_argument(prefix + " must be of type: " + type),
m_prefix(std::move(prefix)),
m_type(std::move(type))
{}
private:
std::string m_prefix;
std::string m_type;
TypeErrorException(const char *name, std::string const& type, std::string const& value)
: std::invalid_argument(util::format("%1 must be of type '%2', got (%3)",
name ? name : "JS value", type, value))
{}
};
template<typename T>
@ -138,8 +137,7 @@ struct Value {
#define VALIDATED(return_t, type) \
static return_t validated_to_##type(ContextType ctx, const ValueType &value, const char *name = nullptr) { \
if (!is_##type(ctx, value)) { \
std::string prefix = name ? std::string("'") + name + "'" : "JS value"; \
throw TypeErrorException(prefix, #type); \
throw TypeErrorException(name, #type, to_string(ctx, value)); \
} \
return to_##type(ctx, value); \
}
@ -352,12 +350,31 @@ REALM_JS_INLINE void set_internal(const typename T::Object &object, typename Cla
template<typename T>
inline bool Value<T>::is_valid_for_property(ContextType context, const ValueType &value, const Property& prop)
{
if (prop.is_nullable && (is_null(context, value) || is_undefined(context, value))) {
if (is_nullable(prop.type) && (is_null(context, value) || is_undefined(context, value))) {
return true;
}
using PropertyType = realm::PropertyType;
switch (prop.type) {
using realm::PropertyType;
if (realm::is_array(prop.type)) {
if (prop.type != PropertyType::Object) {
return false;
}
// FIXME: Do we need to validate the types of the contained objects?
if (is_array(context, value)) {
return true;
}
if (is_object(context, value)) {
auto object = to_object(context, value);
return Object<T>::template is_instance<ResultsClass<T>>(context, object)
|| Object<T>::template is_instance<ListClass<T>>(context, object);
}
return false;
}
switch (prop.type & ~PropertyType::Flags) {
case PropertyType::Int:
case PropertyType::Float:
case PropertyType::Double:
@ -372,32 +389,24 @@ inline bool Value<T>::is_valid_for_property(ContextType context, const ValueType
return is_date(context, value);
case PropertyType::Object:
return true;
case PropertyType::Array:
// FIXME: Do we need to validate the types of the contained objects?
if (is_array(context, value)) {
return true;
}
if (is_object(context, value)) {
auto object = to_object(context, value);
return Object<T>::template is_instance<ResultsClass<T>>(context, object)
|| Object<T>::template is_instance<ListClass<T>>(context, object);
}
return false;
case PropertyType::Any:
case PropertyType::LinkingObjects:
return false;
default:
REALM_UNREACHABLE();
}
REALM_UNREACHABLE();
return false;
}
inline std::string js_type_name_for_property_type(PropertyType type)
inline std::string js_type_name_for_property_type(realm::PropertyType type)
{
switch (type) {
using realm::PropertyType;
if (realm::is_array(type)) {
if (type == PropertyType::LinkingObjects) {
throw std::runtime_error("LinkingObjects' type is not supported");
}
return "array";
}
switch (type & ~PropertyType::Flags) {
case PropertyType::Int:
case PropertyType::Float:
case PropertyType::Double:
@ -412,17 +421,11 @@ inline std::string js_type_name_for_property_type(PropertyType type)
return "binary";
case PropertyType::Object:
return "object";
case PropertyType::Array:
return "array";
case PropertyType::Any:
throw std::runtime_error("'Any' type is not supported");
case PropertyType::LinkingObjects:
throw std::runtime_error("LinkingObjects' type is not supported");
default:
REALM_UNREACHABLE();
}
REALM_UNREACHABLE();
return "<unknown>";
}
} // js

View File

@ -44,7 +44,6 @@
"msvs_settings": {
"VCCLCompilerTool": {
"RuntimeTypeInfo": "true",
"AdditionalOptions": [ "/MDd" ]
},
}
},
@ -52,7 +51,6 @@
"msvs_settings": {
"VCCLCompilerTool": {
"RuntimeTypeInfo": "true",
"AdditionalOptions": [ "/MD" ]
},
}
}
@ -64,4 +62,4 @@
},
"msvs_disabled_warnings": [ 4068, 4101, 4244, 4996 ],
}
}
}

View File

@ -1,7 +1,6 @@
'use strict';
function node_require(module) {
return require(module);
}
let fs = node_require("fs");
let path = node_require("path");
@ -11,11 +10,11 @@ const DEFAULT_ADMIN_TOKEN_PATH = path.join(__dirname, "..", "..", "object-server
const ADMIN_TOKEN_PATH = process.env.ADMIN_TOKEN_PATH || DEFAULT_ADMIN_TOKEN_PATH;
function getAdminToken() {
if(fs.existsSync(ADMIN_TOKEN_PATH)) {
return fs.readFileSync(ADMIN_TOKEN_PATH, 'utf-8');
} else {
throw new Error("Missing the file with an admin token: " + ADMIN_TOKEN_PATH);
}
if (fs.existsSync(ADMIN_TOKEN_PATH)) {
return fs.readFileSync(ADMIN_TOKEN_PATH, 'utf-8');
} else {
throw new Error("Missing the file with an admin token: " + ADMIN_TOKEN_PATH);
}
}
function random(min, max) {
@ -24,66 +23,71 @@ function random(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
const newAdminName = 'admin' + random(1, 100000);
const password = '123';
exports.createAdminUser = function () {
let nonTokenUser, userIdentity, admin_token_user
return new Promise((resolve, reject) => {
let isAdminRetryCounter = 0;
let newAdminName = 'admin' + random(1, 100000);
let password = '123';
Realm.Sync.User.register('http://localhost:9080', newAdminName, password, (error, user) => {
if (error) {
reject(error);
} else {
let userIdentity = user.identity;
user.logout();
return;
}
nonTokenUser = user
userIdentity = user.identity;
user.logout();
let admin_token_user = Realm.Sync.User.adminUser(getAdminToken());
admin_token_user = Realm.Sync.User.adminUser(getAdminToken(), 'http://localhost:9080');
const config = {
sync: {
user: admin_token_user,
url: `realm://localhost:9080/__admin`,
error: err =>
console.log('Error opening __admin realm ' + err.user + ' ' + err.url + ' ' + err.state),
const config = {
sync: {
user: admin_token_user,
url: 'realm://localhost:9080/__admin',
error: err => {
reject(new Error('Error opening __admin realm error:' + err.user + ' url:' + err.url + ' state:' + err.state));
}
};
}
};
Realm.open(config).then(realm => {
let pendingAdminUser = realm.objectForPrimaryKey('User', userIdentity);
realm.write(() => {
pendingAdminUser.isAdmin = true;
resolve(Realm.open(config));
});
}).then(realm => {
let pendingAdminUser = realm.objectForPrimaryKey('User', userIdentity);
realm.write(() => {
pendingAdminUser.isAdmin = true;
});
admin_token_user.logout();
}).then(() => {
return new Promise((resolve, reject) => {
let isAdminRetryCounter = 0;
let waitForServerToUpdateAdminUser = function () {
isAdminRetryCounter++;
if (isAdminRetryCounter > 10) {
reject("admin-user-helper: Create admin user timeout");
return;
}
Realm.Sync.User.login('http://localhost:9080', newAdminName, password, (error, newAdminUser) => {
if (error) {
reject(error);
return;
}
let isAdmin = newAdminUser.isAdmin;
nonTokenUser.logout();
if (!isAdmin) {
setTimeout(waitForServerToUpdateAdminUser, 500);
return;
}
resolve({
username: newAdminName,
password
});
admin_token_user.logout();
}).then(() => {
let waitForServerToUpdateAdminUser = function () {
isAdminRetryCounter++;
if (isAdminRetryCounter > 10) {
reject("admin-user-helper: Create admin user timeout");
return;
}
Realm.Sync.User.login('http://localhost:9080', newAdminName, password, (error, newAdminUser) => {
if (error) {
reject(error);
} else {
let isAdmin = newAdminUser.isAdmin;
user.logout();
if (!isAdmin) {
setTimeout(waitForServerToUpdateAdminUser, 500);
return;
}
resolve({
username: newAdminName,
password
});
}
});
}
waitForServerToUpdateAdminUser();
});
}
waitForServerToUpdateAdminUser();
});
});
}

View File

@ -76,7 +76,7 @@ if (Realm.Sync) {
new Realm({
encryptionKey: new Int8Array(64),
sync: {
user: Realm.Sync.User.adminUser('fake-token'),
user: Realm.Sync.User.adminUser('fake-token', 'http://fake-server'),
url: 'realm://fake-server'
}
});

View File

@ -87,14 +87,15 @@ exports.prepare = function(done) {
return;
}
let helper = require('./admin-user-helper');
helper.createAdminUser().then(userInfo => {
global.testAdminUserInfo = userInfo;
done();
})
.catch(error => {
console.error("Error running admin-user-helper: " + error);
require('./admin-user-helper')
.createAdminUser()
.then(userInfo => {
global.testAdminUserInfo = userInfo;
done();
})
.catch(error => {
console.error("Error running admin-user-helper", error);
done.fail(error);
});
};

View File

@ -67,7 +67,7 @@ module.exports = {
TestCase.assertThrows(function() {
new Realm({schemaVersion: 1, schema: []});
}, "Realm already opened at a different schema version");
TestCase.assertEqual(new Realm().schemaVersion, 0);
TestCase.assertEqual(new Realm({schemaVersion: 0}).schemaVersion, 0);
@ -144,7 +144,7 @@ module.exports = {
}
}]});
}, "Property 'InvalidObject.integer' declared as origin of linking objects property 'InvalidObject.linkingObjects' is not a link")
// linkingObjects property where the source property links elsewhere
TestCase.assertThrows(function() {
new Realm({schema: [{
@ -204,7 +204,7 @@ module.exports = {
testRealmSchemaVersion: function() {
TestCase.assertEqual(Realm.schemaVersion(Realm.defaultPath), -1);
var realm = new Realm({schema: []});
TestCase.assertEqual(realm.schemaVersion, 0);
TestCase.assertEqual(Realm.schemaVersion(Realm.defaultPath), 0);
@ -216,7 +216,7 @@ module.exports = {
testRealmWrite: function() {
var realm = new Realm({schema: [schemas.IntPrimary, schemas.AllTypes, schemas.TestObject, schemas.LinkToAllTypes]});
// exceptions should be propogated
TestCase.assertThrows(function() {
realm.write(function() {
@ -301,7 +301,7 @@ module.exports = {
links = realm.create('LinkTypesObject', {});
});
for (var name in schemas.NullableBasicTypes.properties) {
TestCase.assertEqual(basic[name], null);
TestCase.assertEqual(basic[name], null);
}
TestCase.assertEqual(links.objectCol, null);
TestCase.assertEqual(links.arrayCol.length, 0);
@ -445,8 +445,8 @@ module.exports = {
});
// primary key
IndexedSchema.properties = { boolCol: {type: 'bool', indexed: true} };
IndexedSchema.primaryKey = 'boolCol';
IndexedSchema.properties = { intCol: {type: 'int', indexed: true} };
IndexedSchema.primaryKey = 'intCol';
// Test this doesn't throw
new Realm({schema: [IndexedSchema], path: '5.realm'});
@ -825,9 +825,9 @@ module.exports = {
},
testSchema: function() {
var originalSchema = [schemas.TestObject, schemas.BasicTypes, schemas.NullableBasicTypes, schemas.IndexedTypes, schemas.IntPrimary,
var originalSchema = [schemas.TestObject, schemas.BasicTypes, schemas.NullableBasicTypes, schemas.IndexedTypes, schemas.IntPrimary,
schemas.PersonObject, schemas.LinkTypes, schemas.LinkingObjectsObject];
var schemaMap = {};
originalSchema.forEach(function(objectSchema) {
if (objectSchema.schema) { // for PersonObject
@ -857,11 +857,11 @@ module.exports = {
var prop1 = returned.properties[propName];
var prop2 = original.properties[propName];
if (prop1.type == 'object') {
TestCase.assertEqual(prop1.objectType, isString(prop2) ? prop2 : prop2.objectType);
TestCase.assertEqual(prop1.objectType, isString(prop2) ? prop2 : prop2.objectType);
TestCase.assertEqual(prop1.optional, true);
}
else if (prop1.type == 'list') {
TestCase.assertEqual(prop1.objectType, prop2.objectType);
TestCase.assertEqual(prop1.objectType, prop2.objectType);
TestCase.assertEqual(prop1.optional, undefined);
}
else if (prop1.type == 'linking objects') {
@ -870,7 +870,7 @@ module.exports = {
TestCase.assertEqual(prop1.optional, undefined);
}
else {
TestCase.assertEqual(prop1.type, isString(prop2) ? prop2 : prop2.type);
TestCase.assertEqual(prop1.type, isString(prop2) ? prop2 : prop2.type);
TestCase.assertEqual(prop1.optional, prop2.optional || undefined);
}
@ -904,13 +904,13 @@ module.exports = {
testErrorMessageFromInvalidWrite: function() {
var realm = new Realm({schema: [schemas.PersonObject]});
TestCase.assertThrowsException(function() {
realm.write(function () {
var p1 = realm.create('PersonObject', { name: 'Ari', age: 10 });
p1.age = "Ten";
});
}, new Error("PersonObject.age must be of type: number"));
}, new Error("PersonObject.age must be of type 'number', got (Ten)"));
},
testErrorMessageFromInvalidCreate: function() {
@ -920,7 +920,7 @@ module.exports = {
realm.write(function () {
var p1 = realm.create('PersonObject', { name: 'Ari', age: 'Ten' });
});
}, new Error("PersonObject.age must be of type: number"));
}, new Error("PersonObject.age must be of type 'number', got (Ten)"));
},
testValidTypesForListProperties: function() {

View File

@ -67,7 +67,7 @@ function assertIsAuthError(error, code, type) {
function failOnError(error) {
if (error) {
throw new Error(`Error ${error} was not expected`);
throw new Error(`Unexpected error in test: ${error}\n${error.stack}`);
}
}
@ -89,7 +89,7 @@ function callbackTest(requestFunc, callback) {
}
module.exports = {
testLogout() {
var username = uuid();
return callbackTest((callback) => Realm.Sync.User.register('http://localhost:9080', username, 'password', callback), (error, user) => {
@ -132,7 +132,7 @@ module.exports = {
TestCase.assertUndefined(user);
});
});
},
},
testRegisterMissingUsername() {
return new Promise((resolve, _reject) => {
@ -301,7 +301,7 @@ module.exports = {
if (!isNodeProcess) {
resolve();
}
if (!global.testAdminUserInfo) {
reject("Test requires an admin user");
}

View File

@ -377,6 +377,14 @@
name = Products;
sourceTree = "<group>";
};
3F0587551F58D19B006F7080 /* Recovered References */ = {
isa = PBXGroup;
children = (
629FEF95D64747E9A56D4D0C /* libRealmReact.a */,
);
name = "Recovered References";
sourceTree = "<group>";
};
49D7AFC5B84C4E5599233B8E /* Frameworks */ = {
isa = PBXGroup;
children = (
@ -442,6 +450,7 @@
832341AE1AAA6A7D00B99B32 /* Libraries */,
83CBBA001A601CBA00E9B192 /* Products */,
49D7AFC5B84C4E5599233B8E /* Frameworks */,
3F0587551F58D19B006F7080 /* Recovered References */,
);
indentWidth = 2;
sourceTree = "<group>";
@ -871,12 +880,12 @@
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = ../../ios/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
);
INFOPLIST_FILE = ../../ios/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactTests.app/ReactTests";
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../ios";
@ -889,12 +898,12 @@
BUNDLE_LOADER = "$(TEST_HOST)";
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = NO;
INFOPLIST_FILE = ../../ios/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
);
INFOPLIST_FILE = ../../ios/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReactTests.app/ReactTests";
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../ios";