Skip to content

Commit

Permalink
RJS-2732: Support updating the App's base URL via experimental expo…
Browse files Browse the repository at this point in the history
…rt (#6518)

* Add experimental file to extend 'App'.

* Expose experimental module.

* Add getter for base url.

* Test experimental module.

* Rename module to 'base-url'.

* Add TS error for setting the property.

* Add experimental to TS docs.

* Add implementation to the added functions.

* Rename to 'updateBaseUrl()'.

* Return the promise directly instead of using 'async await'.

* Update expected base url from 'realm..' to 'services.cloud..'.

* Update public API docs.

* Update arg name.

* Separate tests.

* Help Metro resolve the correct file for RN.

* Isolate test for baseUrl getter.

* Remove `unstable_enablePackageExports` from metro config.

Co-authored-by: Kræn Hansen <kraen.hansen@mongodb.com>

* Update comment about the need of 'realm/experimental/base-url.js'.

* Elaborate in API docs.

* Add skipped empty test for resetting URL.

* Allow 'null' as arg to reset the URL.

* Add CHANGELOG entry.

---------

Co-authored-by: Kræn Hansen <kraen.hansen@mongodb.com>
  • Loading branch information
elle-j and kraenhansen authored May 1, 2024
1 parent 56112c7 commit 7f6535f
Show file tree
Hide file tree
Showing 12 changed files with 160 additions and 15 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* None

### Enhancements
* None
* Experimental feature: The new instance members `App.baseUrl` and `App.updateBaseUrl()` allow for retrieving and updating the base URL currently used for requests sent to Atlas App Services. These APIs are only available after importing `"realm/experimental/base-url"`. ([#6518](https://github.com/realm/realm-js/pull/6518))

### Fixed
* <How to hit and notice issue? what was the impact?> ([#????](https://github.com/realm/realm-js/issues/????), since v?.?.?)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1107,7 +1107,7 @@ PODS:
- React-Core
- React-jsi
- ReactTestApp-Resources (1.0.0-dev)
- RealmJS (12.7.0-rc.0):
- RealmJS (12.7.1):
- React
- RNFS (2.20.0):
- React-Core
Expand Down Expand Up @@ -1356,7 +1356,7 @@ SPEC CHECKSUMS:
ReactNativeHost: 446b46cbfc2d16420bfd249e9064802e929fa9b7
ReactTestApp-DevSupport: 5cd1b02b4d146811d29dc2455a249f0743fda504
ReactTestApp-Resources: d200e68756fa45c648f369210bd7ee0c14759f5a
RealmJS: 0c85b5fd6406447f4526d7b73d0a8025cd8b342a
RealmJS: 3fdc3b6cb6d4ff67eaf0e5f7f861be51304e7525
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
Yoga: 805bf71192903b20fc14babe48080582fee65a80
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
////////////////////////////////////////////////////////////////////////////

const { makeMetroConfig } = require("@rnx-kit/metro-config");

module.exports = makeMetroConfig({
transformer: {
getTransformOptions: async () => ({
Expand Down
15 changes: 5 additions & 10 deletions integration-tests/tests/src/hooks/import-app-before.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
//
////////////////////////////////////////////////////////////////////////////

import Realm from "realm";
import Realm, { AppConfiguration } from "realm";

import { AppConfig, AppImporter, Credentials } from "@realm/app-importer";
import { mongodbServiceType } from "../utils/ExtendedAppConfigBuilder";
Expand All @@ -39,14 +39,6 @@ export { baseUrl };

const allowSkippingServerTests = typeof environment.baseUrl === "undefined" && missingServer !== false;

export type AppConfigurationRelaxed = {
id?: string;
baseUrl?: string;
timeout?: number;
multiplexSessions?: boolean;
baseFilePath?: string;
};

const credentials: Credentials =
typeof publicKey === "string" && typeof privateKey === "string"
? {
Expand Down Expand Up @@ -94,7 +86,10 @@ function ensureSkippedAppImportAfterHook() {
* If the `missingServer` context is set the suite will be skipped.
* If the import fails due to a connection refusal, the suite will be skipped and a warning printed at the end of the test run.
*/
export function importAppBefore(config: AppConfig | { config: AppConfig }, sdkConfig?: AppConfigurationRelaxed): void {
export function importAppBefore(
config: AppConfig | { config: AppConfig },
sdkConfig?: Partial<AppConfiguration>,
): void {
// Unwrap when passed a builder directly
if ("config" in config) {
return importAppBefore(config.config, sdkConfig);
Expand Down
2 changes: 2 additions & 0 deletions integration-tests/tests/src/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import "./tests/credentials/email-password";
import "./tests/credentials/function";
import "./tests/credentials/jwt";

import "./tests/experimental/base-url";

import "./tests/sync/app";
import "./tests/sync/asymmetric";
import "./tests/sync/client-reset";
Expand Down
55 changes: 55 additions & 0 deletions integration-tests/tests/src/tests/experimental/base-url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
////////////////////////////////////////////////////////////////////////////
//
// Copyright 2024 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////

import { expect } from "chai";
import "realm/experimental/base-url";

import { baseUrl as originalBaseUrl, importAppBefore } from "../../hooks";
import { buildAppConfig } from "../../utils/build-app-config";

describe.skipIf(environment.missingServer, "Base URL", () => {
importAppBefore(buildAppConfig("with-anon").anonAuth());

it("returns the base URL used", function (this: AppContext) {
expect(this.app.baseUrl).equals(originalBaseUrl);
});

// TODO: Should implement when I've got a working fetch mock.
it.skip("updates the URL", async function (this: AppContext) {
// TODO
});

it.skip("resets to default URL", async function (this: AppContext) {
// TODO
});

it("throws when assigning via setter", function (this: AppContext) {
// @ts-expect-error Assigning to read-only property.
expect(() => (this.app.baseUrl = "new URL")).to.throw("Cannot assign the base URL, please use 'updateBaseUrl()'");

expect(this.app.baseUrl).equals(originalBaseUrl);
});

it("rejects when updating to invalid URL", async function (this: AppContext) {
await expect(this.app.updateBaseUrl("https://invalid")).to.be.rejectedWith(
"request to https://invalid/api/client/",
);

expect(this.app.baseUrl).equals(originalBaseUrl);
});
});
2 changes: 1 addition & 1 deletion integration-tests/tests/tsconfig.common.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"composite": true,
"target": "es2022",
"module": "es2022",
"moduleResolution": "node",
"moduleResolution": "Bundler",
"useDefineForClassFields": false,
"strict": true,
"strictFunctionTypes": false,
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/tests/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
{ "path": "./tsconfig.common.json" },
{ "path": "./tsconfig.node.json" }
]
}
}
2 changes: 2 additions & 0 deletions packages/realm/bindgen/js_opt_in_spec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,8 @@ classes:
- unsubscribe
- call_function
- make_streaming_request
- update_base_url
- get_base_url

WatchStream:
methods:
Expand Down
29 changes: 29 additions & 0 deletions packages/realm/experimental/base-url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
////////////////////////////////////////////////////////////////////////////
//
// Copyright 2024 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////

// Our use of `exports` in `packages/realm/package.json` is not enabled by
// default when using Metro and RN. In these cases, modules imported from
// "realm/experimental" will search for the file in the same path, rather
// than what is pointed to under `exports`. Thus, we use this .js file to
// in turn import the necessary module.

// (Enabling `unstable_enablePackageExports` in the metro config unexpectedly
// does not work.)

/* eslint-env commonjs */
module.exports = require("../dist/experimental/base-url");
4 changes: 4 additions & 0 deletions packages/realm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
"node": "./dist/platform/node/index.js",
"react-native": "./index.react-native.js"
},
"./experimental/base-url": {
"types": "./dist/public-types/experimental/base-url.d.ts",
"default": "./dist/experimental/base-url.js"
},
"./scripts/submit-analytics": "./scripts/submit-analytics.mjs",
"./react-native.config.js": "./react-native.config.js",
"./package.json": "./package.json"
Expand Down
57 changes: 57 additions & 0 deletions packages/realm/src/experimental/base-url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
////////////////////////////////////////////////////////////////////////////
//
// Copyright 2024 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////

import { App } from "../app-services/App";

declare module "../app-services/App" {
interface App {
/**
* Get the current base URL used for sending requests to Atlas App Services.
*
* If an {@link App.updateBaseUrl | updateBaseUrl} operation is currently in
* progress, this value will not be updated with the new value until that
* operation has completed.
* @experimental This feature is experimental and may be changed or removed.
*/
get baseUrl(): string;

/**
* Update the base URL used for sending requests to Atlas App Services. If this is
* set to an empty string or `null`, it will reset the base URL to the default one.
*
* If this operation fails, the app will continue to use the original base URL.
* If another {@link App} operation is started while this function is in progress,
* that request will use the original base URL location information.
* @experimental This feature is experimental and may be changed or removed.
*/
updateBaseUrl(newUrl: string | null): Promise<void>;
}
}

Object.defineProperty(App.prototype, "baseUrl", {
get(this: App) {
return this.internal.getBaseUrl();
},
set() {
throw new Error("Cannot assign the base URL, please use 'updateBaseUrl()'.");
},
});

App.prototype.updateBaseUrl = function (this: App, newUrl: string | null) {
return this.internal.updateBaseUrl(newUrl ?? undefined);
};

0 comments on commit 7f6535f

Please sign in to comment.