mirror of
https://github.com/status-im/realm-js.git
synced 2025-01-10 14:25:58 +00:00
Merge branch 'master' of github.com:realm/realm-js into kneth/updating-tg-branch
This commit is contained in:
commit
188f985aed
@ -11,9 +11,12 @@
|
||||
* Added additional parameter for `Realm.open` and `Realm.openAsync` for download progress notifications
|
||||
* Added `Realm.deleteFile` for deleting a Realm (#363).
|
||||
* Added `Realm.deleteModel` for deleting a Realm model in a migration (#573).
|
||||
* Added support for in-memory Realms.
|
||||
* `Realm.Sync.User.login`, `Realm.Sync.User.register`, and `Realm.Sync.User.registerWithProvider` return Promises and deprecate the callback style for them. Callbacks will continue to work for backward compatibility.
|
||||
|
||||
### Bug fixes
|
||||
* Adding missing TypeScript definitions; Permissions (#1283), `setFeatureToken()`, and instructions (#1298).
|
||||
* Removed `loginWithProvider` from TypeScript definition files. This API never existed and was incorrectly added.
|
||||
|
||||
1.11.1 Release notes (2017-9-1)
|
||||
=============================================================
|
||||
|
@ -278,6 +278,11 @@ Realm.defaultPath;
|
||||
* will be skipped if another process is accessing it.
|
||||
* @property {string} [path={@link Realm.defaultPath}] - The path to the file where the
|
||||
* Realm database should be stored.
|
||||
* @property {boolean} [inMemory=false] - Specifies if this Realm should be opened in-memory. This
|
||||
* still requires a path (can be the default path) to identify the Realm so other processes can
|
||||
* open the same Realm. The file will also be used as swap space if the Realm becomes bigger than
|
||||
* what fits in memory, but it is not persistent and will be removed when the last instance
|
||||
* is closed.
|
||||
* @property {boolean} [readOnly=false] - Specifies if this Realm should be opened as read-only.
|
||||
* @property {Array<Realm~ObjectClass|Realm~ObjectSchema>} [schema] - Specifies all the
|
||||
* object types in this Realm. **Required** when first creating a Realm at this `path`.
|
||||
|
@ -135,9 +135,10 @@ class User {
|
||||
* @param {string} server - authentication server
|
||||
* @param {string} username
|
||||
* @param {string} password
|
||||
* @param {function(error, user)} callback - called with the following arguments:
|
||||
* @param {function(error, user)} [callback] - called with the following arguments:
|
||||
* - `error` - an Error object is provided on failure
|
||||
* - `user` - a valid User object on success
|
||||
* @returns {void|Promise<User>} Returns a promise with a user if the callback was not specified
|
||||
*/
|
||||
static login(server, username, password, callback) {}
|
||||
|
||||
@ -148,9 +149,10 @@ class User {
|
||||
* @param {string} options.provider - The provider type
|
||||
* @param {string} options.providerToken - The access token for the given provider
|
||||
* @param {object} [options.userInfo] - A map containing additional data required by the provider
|
||||
* @param {function(error, User)} callback - called with the following arguments:
|
||||
* @param {function(error, User)} [callback] - an optional callback called with the following arguments:
|
||||
* - `error` - an Error object is provided on failure
|
||||
* - `user` - a valid User object on success
|
||||
* @return {void|Promise<User>} Returns a promise with a user if the callback was not specified
|
||||
*/
|
||||
static registerWithProvider(server, options, callback) {}
|
||||
|
||||
@ -159,9 +161,10 @@ class User {
|
||||
* @param {string} server - authentication server
|
||||
* @param {string} username
|
||||
* @param {string} password
|
||||
* @param {function(error, user)} callback - called with the following arguments:
|
||||
* @param {function(error, user)} [callback] - called with the following arguments:
|
||||
* - `error` - an Error object is provided on failure
|
||||
* - `user` - a valid User object on success
|
||||
* @return {void|Promise<User>} Returns a promise with a user if the callback was not specified
|
||||
*/
|
||||
static register(server, username, password, callback) {}
|
||||
|
||||
|
@ -55,6 +55,7 @@ function setupRealm(realm, realmId) {
|
||||
'empty',
|
||||
'path',
|
||||
'readOnly',
|
||||
'inMemory',
|
||||
'schema',
|
||||
'schemaVersion',
|
||||
'syncSession',
|
||||
|
@ -19,7 +19,12 @@
|
||||
'use strict';
|
||||
|
||||
function AuthError(problem) {
|
||||
Error.call(this, problem.title);
|
||||
const error = Error.call(this, problem.title);
|
||||
|
||||
this.name = 'AuthError';
|
||||
this.message = error.message;
|
||||
this.stack = error.stack;
|
||||
|
||||
Object.assign(this, problem);
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,9 @@ module.exports = function(realmConstructor) {
|
||||
},
|
||||
|
||||
openAsync(config, callback, progressCallback) {
|
||||
const message = "Realm.openAsync is now deprecated in favor of Realm.open. This function will be removed in future versions.";
|
||||
(console.warn || console.log).call(console, message);
|
||||
|
||||
realmConstructor._waitForDownload(config,
|
||||
(syncSession) => {
|
||||
if (progressCallback) {
|
||||
@ -93,7 +96,7 @@ module.exports = function(realmConstructor) {
|
||||
//FIXME: RN hangs here. Remove when node's makeCallback alternative is implemented
|
||||
setTimeout(() => { callback(null, syncedRealm); }, 1);
|
||||
} catch (e) {
|
||||
callback(e);
|
||||
setTimeout(() => { callback(e); }, 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
20
lib/index.d.ts
vendored
20
lib/index.d.ts
vendored
@ -80,6 +80,7 @@ declare namespace Realm {
|
||||
shouldCompactOnLaunch?: (totalBytes: number, usedBytes: number) => boolean;
|
||||
path?: string;
|
||||
readOnly?: boolean;
|
||||
inMemory?: boolean;
|
||||
schema?: ObjectClass[] | ObjectSchema[];
|
||||
schemaVersion?: number;
|
||||
sync?: Realm.Sync.SyncConfiguration;
|
||||
@ -264,10 +265,25 @@ declare namespace Realm.Sync {
|
||||
readonly server: string;
|
||||
readonly token: string;
|
||||
static adminUser(adminToken: string, server?: string): User;
|
||||
|
||||
/**
|
||||
* @deprecated, to be removed in future versions
|
||||
*/
|
||||
static login(server: string, username: string, password: string, callback: (error: any, user: User) => void): void;
|
||||
static loginWithProvider(server: string, provider: string, providerToken: string, callback: (error: any, user: User) => void): void;
|
||||
static login(server: string, username: string, password: string): Promise<Realm.Sync.User>;
|
||||
|
||||
/**
|
||||
* @deprecated, to be removed in future versions
|
||||
*/
|
||||
static register(server: string, username: string, password: string, callback: (error: any, user: User) => void): void;
|
||||
static register(server: string, username: string, password: string): Promise<Realm.Sync.User>;
|
||||
|
||||
/**
|
||||
* @deprecated, to be removed in versions
|
||||
*/
|
||||
static registerWithProvider(server: string, options: { provider: string, providerToken: string, userInfo: any }, callback: (error: Error | null, user: User | null) => void): void;
|
||||
static registerWithProvider(server: string, options: { provider: string, providerToken: string, userInfo: any }): Promise<Realm.Sync.User>;
|
||||
|
||||
logout(): void;
|
||||
openManagementRealm(): Realm;
|
||||
retrieveAccount(provider: string, username: string): Promise<Account>;
|
||||
@ -375,6 +391,7 @@ declare namespace Realm.Sync {
|
||||
function removeListener(regex: string, name: string, changeCallback: (changeEvent: ChangeEvent) => void): void;
|
||||
function setLogLevel(logLevel: 'all' | 'trace' | 'debug' | 'detail' | 'info' | 'warn' | 'error' | 'fatal' | 'off'): void;
|
||||
function setFeatureToken(token: string): void;
|
||||
|
||||
/**
|
||||
* @deprecated, to be removed in 2.0
|
||||
*/
|
||||
@ -446,6 +463,7 @@ declare class Realm {
|
||||
*/
|
||||
static open(config: Realm.Configuration): ProgressPromise;
|
||||
/**
|
||||
* @deprecated in favor of `Realm.open`
|
||||
* Open a realm asynchronously with a callback. If the realm is synced, it will be fully synchronized before it is available.
|
||||
* @param {Configuration} config
|
||||
* @param {Function} callback will be called when the realm is ready.
|
||||
|
@ -121,6 +121,15 @@ function refreshAccessToken(user, localRealmPath, realmUrl) {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The base authentication method. It fires a JSON POST to the server parameter plus the auth url
|
||||
* For example, if the server parameter is `http://myapp.com`, this url will post to `http://myapp.com/auth`
|
||||
* @param {object} userConstructor
|
||||
* @param {string} server the http or https server url
|
||||
* @param {object} json the json to post to the auth endpoint
|
||||
* @param {Function} callback an optional callback with an error and user parameter
|
||||
* @returns {Promise} only returns a promise if the callback parameter was omitted
|
||||
*/
|
||||
function _authenticate(userConstructor, server, json, callback) {
|
||||
json.app_id = '';
|
||||
const url = auth_url(server);
|
||||
@ -130,21 +139,32 @@ function _authenticate(userConstructor, server, json, callback) {
|
||||
headers: postHeaders,
|
||||
open_timeout: 5000
|
||||
};
|
||||
performFetch(url, options)
|
||||
|
||||
const promise = performFetch(url, options)
|
||||
.then((response) => {
|
||||
if (response.status !== 200) {
|
||||
return response.json().then((body) => callback(new AuthError(body)));
|
||||
return response.json().then((body) => Promise.reject(new AuthError(body)));
|
||||
} else {
|
||||
return response.json().then(function (body) {
|
||||
// TODO: validate JSON
|
||||
const token = body.refresh_token.token;
|
||||
const identity = body.refresh_token.token_data.identity;
|
||||
const isAdmin = body.refresh_token.token_data.is_admin;
|
||||
callback(undefined, userConstructor.createUser(server, identity, token, false, isAdmin));
|
||||
})
|
||||
return userConstructor.createUser(server, identity, token, false, isAdmin);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (callback) {
|
||||
promise.then(user => {
|
||||
callback(null, user);
|
||||
})
|
||||
.catch(callback);
|
||||
.catch(err => {
|
||||
callback(err);
|
||||
});
|
||||
} else {
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
|
||||
const staticMethods = {
|
||||
@ -171,20 +191,34 @@ const staticMethods = {
|
||||
|
||||
register(server, username, password, callback) {
|
||||
checkTypes(arguments, ['string', 'string', 'string', 'function']);
|
||||
_authenticate(this, server, {
|
||||
const json = {
|
||||
provider: 'password',
|
||||
user_info: { password: password, register: true },
|
||||
data: username
|
||||
}, callback);
|
||||
};
|
||||
|
||||
if (callback) {
|
||||
const message = "register(..., callback) is now deprecated in favor of register(): Promise<User>. This function argument will be removed in future versions.";
|
||||
(console.warn || console.log).call(console, message);
|
||||
}
|
||||
|
||||
return _authenticate(this, server, json, callback);
|
||||
},
|
||||
|
||||
login(server, username, password, callback) {
|
||||
checkTypes(arguments, ['string', 'string', 'string', 'function']);
|
||||
_authenticate(this, server, {
|
||||
const json = {
|
||||
provider: 'password',
|
||||
user_info: { password: password },
|
||||
data: username
|
||||
}, callback);
|
||||
};
|
||||
|
||||
if (callback) {
|
||||
const message = "login(..., callback) is now deprecated in favor of login(): Promise<User>. This function argument will be removed in future versions.";
|
||||
(console.warn || console.log).call(console, message);
|
||||
}
|
||||
|
||||
return _authenticate(this, server, json, callback);
|
||||
},
|
||||
|
||||
registerWithProvider(server, options, callback) {
|
||||
@ -202,16 +236,21 @@ const staticMethods = {
|
||||
checkTypes(arguments, ['string', 'object', 'function']);
|
||||
}
|
||||
|
||||
let reqOptions = {
|
||||
let json = {
|
||||
provider: options.provider,
|
||||
data: options.providerToken,
|
||||
};
|
||||
|
||||
if (options.userInfo) {
|
||||
reqOptions.user_info = options.userInfo;
|
||||
json.user_info = options.userInfo;
|
||||
}
|
||||
|
||||
_authenticate(this, server, reqOptions, callback);
|
||||
if (callback) {
|
||||
const message = "registerWithProvider(..., callback) is now deprecated in favor of registerWithProvider(): Promise<User>. This function argument will be removed in future versions.";
|
||||
(console.warn || console.log).call(console, message);
|
||||
}
|
||||
|
||||
return _authenticate(this, server, json, callback);
|
||||
},
|
||||
|
||||
_refreshAccessToken: refreshAccessToken
|
||||
@ -240,13 +279,11 @@ const instanceMethods = {
|
||||
},
|
||||
retrieveAccount(provider, provider_id) {
|
||||
checkTypes(arguments, ['string', 'string']);
|
||||
|
||||
const url = url_parse(this.server);
|
||||
url.set('pathname', `/api/providers/${provider}/accounts/${provider_id}`);
|
||||
const headers = {
|
||||
Authorization: this.token
|
||||
};
|
||||
|
||||
const options = {
|
||||
method: 'GET',
|
||||
headers,
|
||||
|
@ -187,6 +187,7 @@ public:
|
||||
static void get_path(ContextType, ObjectType, ReturnValue &);
|
||||
static void get_schema_version(ContextType, ObjectType, ReturnValue &);
|
||||
static void get_schema(ContextType, ObjectType, ReturnValue &);
|
||||
static void get_in_memory(ContextType, ObjectType, ReturnValue &);
|
||||
static void get_read_only(ContextType, ObjectType, ReturnValue &);
|
||||
static void get_is_in_transaction(ContextType, ObjectType, ReturnValue &);
|
||||
#if REALM_ENABLE_SYNC
|
||||
@ -243,6 +244,7 @@ public:
|
||||
{"path", {wrap<get_path>, nullptr}},
|
||||
{"schemaVersion", {wrap<get_schema_version>, nullptr}},
|
||||
{"schema", {wrap<get_schema>, nullptr}},
|
||||
{"inMemory", {wrap<get_in_memory>, nullptr}},
|
||||
{"readOnly", {wrap<get_read_only>, nullptr}},
|
||||
{"isInTransaction", {wrap<get_is_in_transaction>, nullptr}},
|
||||
#if REALM_ENABLE_SYNC
|
||||
@ -380,6 +382,12 @@ void RealmClass<T>::constructor(ContextType ctx, ObjectType this_object, size_t
|
||||
else if (config.path.empty()) {
|
||||
config.path = js::default_path();
|
||||
}
|
||||
|
||||
static const String in_memory_string = "inMemory";
|
||||
ValueType in_memory_value = Object::get_property(ctx, object, in_memory_string);
|
||||
if (!Value::is_undefined(ctx, in_memory_value) && Value::validated_to_boolean(ctx, in_memory_value, "inMemory")) {
|
||||
config.in_memory = true;
|
||||
}
|
||||
|
||||
static const String read_only_string = "readOnly";
|
||||
ValueType read_only_value = Object::get_property(ctx, object, read_only_string);
|
||||
@ -606,6 +614,11 @@ void RealmClass<T>::get_schema(ContextType ctx, ObjectType object, ReturnValue &
|
||||
return_value.set(Schema<T>::object_for_schema(ctx, schema));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::get_in_memory(ContextType ctx, ObjectType object, ReturnValue &return_value) {
|
||||
return_value.set(get_internal<T, RealmClass<T>>(object)->get()->config().in_memory);
|
||||
}
|
||||
|
||||
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().immutable());
|
||||
|
@ -36,7 +36,7 @@ Realm.Sync.User.register('http://localhost:9080', username, 'password', (error,
|
||||
Realm.Sync.User.login('http://localhost:9080', username, 'password', (err, loggedUser) => {
|
||||
if (err) {
|
||||
const loginError = JSON.stringify(err);
|
||||
console.error("download-api-helper failed:\n User.register() error:\n" + registrationError + "\n User.login() error:\n" + loginError);
|
||||
console.error("download-api-helper failed:\n User.register() error:\n" + err + "\n" + registrationError + "\n User.login() error:\n" + loginError);
|
||||
process.exit(-2);
|
||||
}
|
||||
else {
|
||||
|
@ -161,6 +161,36 @@ module.exports = {
|
||||
}]});
|
||||
}, "Property 'InvalidObject.link' declared as origin of linking objects property 'InvalidObject.linkingObjects' links to type 'IntObject'")
|
||||
},
|
||||
|
||||
testRealmConstructorInMemory: function() {
|
||||
// open in-memory realm instance
|
||||
const realm1 = new Realm({inMemory: true, schema: [schemas.TestObject]});
|
||||
realm1.write(function() {
|
||||
realm1.create('TestObject', [1])
|
||||
});
|
||||
TestCase.assertEqual(realm1.inMemory, true);
|
||||
|
||||
// open a second instance of the same realm and check that they share data
|
||||
const realm2 = new Realm({inMemory: true});
|
||||
const objects = realm2.objects('TestObject');
|
||||
TestCase.assertEqual(objects.length, 1);
|
||||
TestCase.assertEqual(objects[0].doubleCol, 1.0);
|
||||
TestCase.assertEqual(realm2.inMemory, true);
|
||||
|
||||
// Close both realms (this should delete the realm since there are no more
|
||||
// references to it.
|
||||
realm1.close();
|
||||
realm2.close();
|
||||
|
||||
// Open the same in-memory realm again and verify that it is now empty
|
||||
const realm3 = new Realm({inMemory: true});
|
||||
TestCase.assertEqual(realm3.schema.length, 0);
|
||||
|
||||
// try to open the same realm in persistent mode (should fail as you cannot mix modes)
|
||||
TestCase.assertThrows(function() {
|
||||
const realm4 = new Realm({});
|
||||
});
|
||||
},
|
||||
|
||||
testRealmConstructorReadOnly: function() {
|
||||
var realm = new Realm({schema: [schemas.TestObject]});
|
||||
|
@ -198,7 +198,7 @@ module.exports = {
|
||||
|
||||
return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH)
|
||||
.then(() => {
|
||||
return promisifiedLogin('http://localhost:9080', username, 'password').then(user => {
|
||||
return Realm.Sync.User.login('http://localhost:9080', username, 'password').then(user => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const accessTokenRefreshed = this;
|
||||
let successCounter = 0;
|
||||
@ -251,7 +251,7 @@ module.exports = {
|
||||
|
||||
return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH)
|
||||
.then(() => {
|
||||
return promisifiedLogin('http://localhost:9080', username, 'password').then(user => {
|
||||
return Realm.Sync.User.login('http://localhost:9080', username, 'password').then(user => {
|
||||
const accessTokenRefreshed = this;
|
||||
let successCounter = 0;
|
||||
let progressNotificationCalled = false;
|
||||
@ -287,7 +287,7 @@ module.exports = {
|
||||
|
||||
return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH)
|
||||
.then(() => {
|
||||
return promisifiedLogin('http://localhost:9080', username, 'password').then(user => {
|
||||
return Realm.Sync.User.login('http://localhost:9080', username, 'password').then(user => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let progressNotificationCalled = false;
|
||||
let config = {
|
||||
@ -334,7 +334,7 @@ module.exports = {
|
||||
|
||||
return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH)
|
||||
.then(() => {
|
||||
return promisifiedLogin('http://localhost:9080', username, 'password').then(user => {
|
||||
return Realm.Sync.User.login('http://localhost:9080', username, 'password').then(user => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const accessTokenRefreshed = this;
|
||||
let successCounter = 0;
|
||||
@ -439,7 +439,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
testErrorHandling() {
|
||||
return promisifiedRegister('http://localhost:9080', uuid(), 'password').then(user => {
|
||||
return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then(user => {
|
||||
return new Promise((resolve, _reject) => {
|
||||
const config = { sync: { user, url: 'realm://localhost:9080/~/myrealm' } };
|
||||
config.sync.error = (sender, error) => {
|
||||
@ -472,7 +472,7 @@ module.exports = {
|
||||
|
||||
return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH)
|
||||
.then(() => {
|
||||
return promisifiedLogin('http://localhost:9080', username, 'password').then(user => {
|
||||
return Realm.Sync.User.login('http://localhost:9080', username, 'password').then(user => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let config = {
|
||||
sync: {
|
||||
@ -507,7 +507,7 @@ module.exports = {
|
||||
|
||||
return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH)
|
||||
.then(() => {
|
||||
return promisifiedLogin('http://localhost:9080', username, 'password').then(user => {
|
||||
return Realm.Sync.User.login('http://localhost:9080', username, 'password').then(user => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let config = {
|
||||
sync: {
|
||||
@ -574,7 +574,7 @@ module.exports = {
|
||||
|
||||
return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH)
|
||||
.then(() => {
|
||||
return promisifiedLogin('http://localhost:9080', username, 'password').then(user => {
|
||||
return Realm.Sync.User.login('http://localhost:9080', username, 'password').then(user => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let config = {
|
||||
sync: {
|
||||
@ -613,7 +613,7 @@ module.exports = {
|
||||
|
||||
return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH)
|
||||
.then(() => {
|
||||
return promisifiedLogin('http://localhost:9080', username, 'password').then(user => {
|
||||
return Realm.Sync.User.login('http://localhost:9080', username, 'password').then(user => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let config = {
|
||||
sync: {
|
||||
|
@ -10,10 +10,12 @@
|
||||
"needle": "^1.3.0",
|
||||
"terminate": "^1.0.8",
|
||||
"tmp": "^0.0.30",
|
||||
"url-parse": "^1.1.7"
|
||||
"url-parse": "^1.1.7",
|
||||
"typescript": "^2.5.2"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jasmine spec/unit_tests.js",
|
||||
"test-sync-integration": "jasmine spec/sync_integration_tests.js"
|
||||
"check-typescript" : "tsc --noEmit --alwaysStrict ./../lib/index.d.ts",
|
||||
"test": "npm run check-typescript && jasmine spec/unit_tests.js",
|
||||
"test-sync-integration": "npm run check-typescript && jasmine spec/sync_integration_tests.js"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user