diff --git a/packages/realm-web-integration-tests/src/app.test.ts b/packages/realm-web-integration-tests/src/app.test.ts index 26d5e728ce..b8a7abd64a 100644 --- a/packages/realm-web-integration-tests/src/app.test.ts +++ b/packages/realm-web-integration-tests/src/app.test.ts @@ -18,13 +18,7 @@ import { expect } from "chai"; -import { - App, - Credentials, - User, - LocalStorage, - getEnvironment, -} from "realm-web"; +import { App, Credentials, User, getEnvironment } from "realm-web"; import { createApp } from "./utils"; diff --git a/packages/realm-web-integration-tests/src/functions.test.ts b/packages/realm-web-integration-tests/src/functions.test.ts index bf51bd3850..65adaf23cc 100644 --- a/packages/realm-web-integration-tests/src/functions.test.ts +++ b/packages/realm-web-integration-tests/src/functions.test.ts @@ -31,9 +31,9 @@ describe("Realm.FunctionsFactory", () => { const app = createApp(); // Login a user const credentials = Credentials.anonymous(); - await app.logIn(credentials); + const user = await app.logIn(credentials); // Call a function - const response = await app.functions.translate("hello", "en_fr"); + const response = await user.functions.translate("hello", "en_fr"); expect(response).to.equal("bonjour"); }); }); diff --git a/packages/realm-web-integration-tests/src/http-service.test.ts b/packages/realm-web-integration-tests/src/http-service.test.ts index a6e293616f..0e4f72ed1a 100644 --- a/packages/realm-web-integration-tests/src/http-service.test.ts +++ b/packages/realm-web-integration-tests/src/http-service.test.ts @@ -16,6 +16,9 @@ // //////////////////////////////////////////////////////////////////////////// +// TODO: Re-enable if the HTTP service gets reintroduced to the API. + +/* import { expect } from "chai"; import { Credentials } from "realm-web"; @@ -43,3 +46,4 @@ describe("HTTP", () => { expect(body.name).equals("realm-js"); }); }); +*/ diff --git a/packages/realm-web-integration-tests/src/iife.test.ts b/packages/realm-web-integration-tests/src/iife.test.ts index aebb00ee5f..60f79e0a99 100644 --- a/packages/realm-web-integration-tests/src/iife.test.ts +++ b/packages/realm-web-integration-tests/src/iife.test.ts @@ -77,9 +77,9 @@ describeIf(typeof window === "object", "IIFE bundle", () => { const app = new Realm.App({ id: APP_ID, baseUrl: BASE_URL }); // Authenticate const credentials = Realm.Credentials.anonymous(); - await app.logIn(credentials); + const user = await app.logIn(credentials); // Call a function - const response = await app.functions.translate("hello", "en_fr"); + const response = await user.functions.translate("hello", "en_fr"); expect(response).to.equal("bonjour"); }); }); diff --git a/packages/realm-web-integration-tests/src/remote-mongodb-service.test.ts b/packages/realm-web-integration-tests/src/remote-mongodb-service.test.ts index 7bcd38abef..8788e809f7 100644 --- a/packages/realm-web-integration-tests/src/remote-mongodb-service.test.ts +++ b/packages/realm-web-integration-tests/src/remote-mongodb-service.test.ts @@ -39,10 +39,14 @@ describe("Remote MongoDB", () => { await app.logIn(credentials); }); - function getCollection() { - const mongodb = app.services.mongodb("local-mongodb"); - const db = mongodb.db("test-database"); - return db.collection("test-collection"); + function getCollection() { + if (app.currentUser) { + const mongodb = app.currentUser.mongoClient("local-mongodb"); + const db = mongodb.db("test-database"); + return db.collection("test-collection"); + } else { + throw new Error("Expected an authenticated user"); + } } let runId: number; @@ -50,7 +54,7 @@ describe("Remote MongoDB", () => { // Genereate a collection runId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // Insert a couple of documents - const collection = getCollection(); + const collection = getCollection(); await collection.insertMany([ { runId, @@ -71,7 +75,7 @@ describe("Remote MongoDB", () => { }); it("can find documents", async () => { - const collection = getCollection(); + const collection = getCollection(); const result = await collection.find( { name: { $exists: true } }, { limit: 10 }, @@ -84,7 +88,7 @@ describe("Remote MongoDB", () => { }); it("returns null when finding no document", async () => { - const collection = getCollection(); + const collection = getCollection(); const result = await collection.findOne({ whatever: "non-existent", }); @@ -92,7 +96,7 @@ describe("Remote MongoDB", () => { }); it("can find a single documents, with projection", async () => { - const collection = getCollection(); + const collection = getCollection(); const result = await collection.findOne( { runId, name: "Bob" }, { projection: { name: 1 } }, @@ -108,7 +112,7 @@ describe("Remote MongoDB", () => { }); it("can upsert a document if no one is found", async () => { - const collection = getCollection(); + const collection = getCollection(); const result = await collection.findOneAndUpdate( { runId, name: "Nobody" }, { name: "Dennis", hiddenField: "a hidden value" }, @@ -125,7 +129,7 @@ describe("Remote MongoDB", () => { }); it("can find and update a document, with projection", async () => { - const collection = getCollection(); + const collection = getCollection(); const result = await collection.findOneAndUpdate( { runId, name: "Bob" }, { name: "Bobby" }, @@ -142,7 +146,7 @@ describe("Remote MongoDB", () => { }); it("can find and replace a document, with projection", async () => { - const collection = getCollection(); + const collection = getCollection(); const result = await collection.findOneAndReplace( { runId, name: "Alice" }, { runId, name: "Alison" }, @@ -163,7 +167,7 @@ describe("Remote MongoDB", () => { }); it("can find and delete a document", async () => { - const collection = getCollection(); + const collection = getCollection(); const countBefore = await collection.count({ runId }); // Delete the document with the last name (Charlie) const result = await collection.findOneAndDelete( @@ -185,7 +189,7 @@ describe("Remote MongoDB", () => { }); it("can aggregate", async () => { - const collection = getCollection(); + const collection = getCollection(); const result = await collection.aggregate([ { $match: { runId } }, { $group: { _id: null, names: { $push: "$name" } } }, @@ -195,7 +199,7 @@ describe("Remote MongoDB", () => { }); it("can count documents, insert a document and count & retrieve it again", async () => { - const collection = getCollection(); + const collection = getCollection(); // Determine the number of documents before insertion const countBefore = await collection.count(); // Insert a document @@ -221,7 +225,7 @@ describe("Remote MongoDB", () => { }); it("can insert many documents", async () => { - const collection = getCollection(); + const collection = getCollection(); // Determine the number of documents before insertion const countBefore = await collection.count(); // Insert a document @@ -240,7 +244,7 @@ describe("Remote MongoDB", () => { }); it("can delete a document", async () => { - const collection = getCollection(); + const collection = getCollection(); const countBefore = await collection.count({ runId }); // Delete the document with the last name (Charlie) const result = await collection.deleteOne({ runId }); @@ -253,7 +257,7 @@ describe("Remote MongoDB", () => { }); it("can delete many documents", async () => { - const collection = getCollection(); + const collection = getCollection(); const countBefore = await collection.count({ runId }); expect(countBefore).equals(3); // Delete all documents in this run @@ -267,7 +271,7 @@ describe("Remote MongoDB", () => { }); it("can update a document", async () => { - const collection = getCollection(); + const collection = getCollection(); // Delete the document with the last name (Charlie) const result = await collection.updateOne( { runId, name: "Alice" }, @@ -281,7 +285,7 @@ describe("Remote MongoDB", () => { }); it("upserts a document when updating and the query match nothing", async () => { - const collection = getCollection(); + const collection = getCollection(); // Delete the document with the last name (Charlie) const result = await collection.updateOne( { runId, name: "Dennis" }, @@ -296,7 +300,7 @@ describe("Remote MongoDB", () => { }); it("can update many documents", async () => { - const collection = getCollection(); + const collection = getCollection(); // Delete the document with the last name (Charlie) const result = await collection.updateMany( { runId }, @@ -309,7 +313,7 @@ describe("Remote MongoDB", () => { }); it("upserts when updating many non-existing documents", async () => { - const collection = getCollection(); + const collection = getCollection(); // Delete the document with the last name (Charlie) const result = await collection.updateMany( { runId, name: "Dennis" }, @@ -327,10 +331,9 @@ describe("Remote MongoDB", () => { this.timeout(10_000); this.slow(2_000); - const mongodb = app.services.mongodb("local-mongodb"); - const db = mongodb.db("test-database"); - const collection = db.collection("test-collection"); + const collection = getCollection(); + // Delete all documents in the collection await collection.deleteMany({}); const sleep = async (time: number) => diff --git a/packages/realm-web/CHANGELOG.md b/packages/realm-web/CHANGELOG.md index 28a7092a29..795f071327 100644 --- a/packages/realm-web/CHANGELOG.md +++ b/packages/realm-web/CHANGELOG.md @@ -1,6 +1,9 @@ ?.?.? Release notes (2020-??-??) ============================================================= +### Breaking Changes +* Removed the `functions` and `services` properties from `App`, use the `functions` property and `mongoClient` method on `User` instances instead. ([#3298](https://github.com/realm/realm-js/pull/3298)) + ### Enhancements * Changing the behaviour when refreshing an access token fails. With this change, if the refresh token cannot be used to refresh an access token, the user is logged out. ([#3269](https://github.com/realm/realm-js/pull/3269)) diff --git a/packages/realm-web/src/App.ts b/packages/realm-web/src/App.ts index 1750137642..9a1b0ca7f1 100644 --- a/packages/realm-web/src/App.ts +++ b/packages/realm-web/src/App.ts @@ -22,10 +22,8 @@ import { } from "realm-network-transport"; import { ObjectId } from "bson"; -import { FunctionsFactory } from "./FunctionsFactory"; import { User, UserState } from "./User"; import { Credentials } from "./Credentials"; -import { create as createServicesFactory } from "./services"; import { EmailPasswordAuth } from "./auth-providers"; import { Storage } from "./storage"; import { AppStorage } from "./AppStorage"; @@ -61,13 +59,6 @@ export class App< FunctionsFactoryType extends object = Realm.DefaultFunctionsFactory, CustomDataType extends object = any > implements Realm.App { - /** @inheritdoc */ - public readonly functions: FunctionsFactoryType & - Realm.BaseFunctionsFactory; - - /** @inheritdoc */ - public readonly services: Realm.Services; - /** @inheritdoc */ public readonly id: string; @@ -149,12 +140,6 @@ export class App< locationUrlContext: this, transport, }); - // Construct the functions factory - this.functions = FunctionsFactory.create( - this.fetcher, - ); - // Construct the services factory - this.services = createServicesFactory(this.fetcher); // Construct the auth providers this.emailPasswordAuth = new EmailPasswordAuth(this.fetcher); // Construct the storage diff --git a/packages/realm-web/src/services/HTTPService.ts b/packages/realm-web/src/services/HTTPService.ts index afe5308e20..5cb7d0fdad 100644 --- a/packages/realm-web/src/services/HTTPService.ts +++ b/packages/realm-web/src/services/HTTPService.ts @@ -30,7 +30,7 @@ type Response = Realm.Services.HTTP.Response; * * @see https://docs.mongodb.com/stitch/services/http/ */ -class HTTPService implements HTTP { +export class HTTPService implements HTTP { /** * The functions factory interface to use when sending requests. */ diff --git a/packages/realm-web/src/services/MongoDBService/index.ts b/packages/realm-web/src/services/MongoDBService/index.ts index 98da377332..153ade6aef 100644 --- a/packages/realm-web/src/services/MongoDBService/index.ts +++ b/packages/realm-web/src/services/MongoDBService/index.ts @@ -31,9 +31,7 @@ export { MongoDBCollection }; * @param collectionName A collection name. * @returns The collection. */ -export function createCollection< - T extends Realm.Services.MongoDB.Document = any ->( +function createCollection( fetcher: Fetcher, serviceName: string, databaseName: string, @@ -56,7 +54,7 @@ export function createCollection< * @param databaseName A database name * @returns The database. */ -export function createDatabase( +function createDatabase( fetcher: Fetcher, serviceName: string, databaseName: string, diff --git a/packages/realm-web/src/services/index.ts b/packages/realm-web/src/services/index.ts index 26b57bc3a8..e88fae5259 100644 --- a/packages/realm-web/src/services/index.ts +++ b/packages/realm-web/src/services/index.ts @@ -16,20 +16,9 @@ // //////////////////////////////////////////////////////////////////////////// -import { Fetcher } from "../Fetcher"; +export { + MongoDBCollection, + createService as createMongoDBService, +} from "./MongoDBService"; -import { createService as createMongoDBRemoteService } from "./MongoDBService"; -import { createService as createHttpService } from "./HTTPService"; - -/** - * Create all services for a particular app. - * - * @param fetcher The fetcher to use when senting requests to the services. - * @returns An object containing functions that create the individual services. - */ -export function create(fetcher: Fetcher): Realm.Services { - return { - mongodb: createMongoDBRemoteService.bind(null, fetcher), - http: createHttpService.bind(null, fetcher), - }; -} +export { HTTPService, createService as createHTTPService } from "./HTTPService"; diff --git a/packages/realm-web/src/tests/App.test.ts b/packages/realm-web/src/tests/App.test.ts index c78de954fd..50a2317011 100644 --- a/packages/realm-web/src/tests/App.test.ts +++ b/packages/realm-web/src/tests/App.test.ts @@ -64,16 +64,6 @@ describe("App", () => { expect(app.id).equals("default-app-id"); }); - it("expose a functions factory", () => { - const app = new App("default-app-id"); - expect(typeof app.functions).equals("object"); - }); - - it("expose a callable functions factory", () => { - const app = new App("default-app-id"); - expect(typeof app.functions.hello).equals("function"); - }); - it("expose a static Credentials factory", () => { expect(typeof App.Credentials).not.equals("undefined"); expect(typeof App.Credentials.anonymous).equals("function"); @@ -454,7 +444,7 @@ describe("App", () => { expect(user.accessToken).not.equals(null); expect(user.refreshToken).not.equals(null); // Manually try again - this time refreshing the access token correctly - const response = await app.functions.foo({ bar: "baz" }); + const response = await user.functions.foo({ bar: "baz" }); expect(response).deep.equals({ bar: "baz" }); // Expect something of the request and response expect(app.requests).deep.equals([ @@ -520,7 +510,7 @@ describe("App", () => { const user = await app.logIn(credentials, false); // Send a request (which will fail) try { - await app.functions.foo({ bar: "baz" }); + await user.functions.foo({ bar: "baz" }); throw new Error("Expected the request to fail"); } catch (err) { expect(err).instanceOf(MongoDBRealmError); @@ -590,9 +580,9 @@ describe("App", () => { baseUrl: "http://localhost:1234", }); const credentials = Credentials.anonymous(); - await app.logIn(credentials, false); + const user = await app.logIn(credentials, false); // Call the function - const response = await app.functions.hello(); + const response = await user.functions.hello(); expect(response).to.deep.equal({ msg: "hi there!" }); expect(transport.requests).to.deep.equal([ LOCATION_REQUEST, @@ -615,17 +605,6 @@ describe("App", () => { ]); }); - it("expose a collection of service factories", () => { - const transport = new MockNetworkTransport([]); - const app = new App({ - id: "my-mocked-app", - transport, - baseUrl: "http://localhost:1337", - }); - expect(app.services).keys(["mongodb", "http"]); - expect(typeof app.services.mongodb).equals("function"); - }); - it("hydrates users from storage", () => { const storage = new MemoryStorage(); const transport = new MockNetworkTransport([]);